半自動添加Grafana 模板之 —- POST提交

  • 2019 年 10 月 5 日
  • 筆記

目前我們生產環境,每次新加DB機器都要人肉去添加模板,這種方式顯然不是一個IT從業人員應該做的。急需完善流程。

看了 grafana官網自帶的http api說明也不夠清晰,於是自己琢磨了下。有了這篇部落格。

1、去grafana裡面生成一個api key,用於和grafana進行http交互。

因為很多時候,公司內有很多組織的,處於許可權控制考慮,我們的監控模板需要放到對應的組織下,只允許對應的業務人員查看。

這裡,我們先新建個組織,例如叫做「會員系統」

然後,去生成1個api key

注意,這個api keys介面只會出現一次,因此需要記住這個key,後續是無法查看到的。

這裡,我們記錄下關鍵資訊如下:

Authorization:  Bearer eyJrIjoiRDd2SXkxU01PUkk4TFVYT0xsM1lQQ1dFaW92dEJIekMiLCJuIjoiZ3JhZmFuYV9hdXRvIiwiaWQiOjE0fQ==

2、添加grafana的數據源,我這裡取名為prom25:

3、製作一個標準模板,後面會用到它,我這裡簡單起見,只用了一個5分鐘負載圖。(實際生產環境這個模板會展示很多指標,操作方法是一樣的)。

這個模板沒問題後,我們來導出json格式的模板文件,如下圖所示:

我這裡導出的json文件全文如下:

{

  "annotations": {

    "list": [

      {

        "builtIn": 1,

        "datasource": "– Grafana –",

        "enable": true,

        "hide": true,

        "iconColor": "rgba(0, 211, 255, 1)",

        "name": "Annotations & Alerts",

        "type": "dashboard"

      }

    ]

  },

  "editable": true,

  "gnetId": null,

  "graphTooltip": 0,

  "hideControls": false,

  "id": 36,

  "links": [],

  "rows": [

    {

      "collapse": false,

      "height": "250px",

      "panels": [

        {

          "aliasColors": {},

          "bars": false,

          "dashLength": 10,

          "dashes": false,

          "datasource": "prom25",

          "decimals": 2,

          "fill": 3,

          "id": 1,

          "legend": {

            "alignAsTable": true,

            "avg": false,

            "current": true,

            "max": true,

            "min": true,

            "show": true,

            "total": false,

            "values": true

          },

          "lines": true,

          "linewidth": 2,

          "links": [],

          "nullPointMode": "null",

          "percentage": false,

          "pointradius": 5,

          "points": false,

          "renderer": "flot",

          "seriesOverrides": [],

          "spaceLength": 10,

          "span": 12,

          "stack": false,

          "steppedLine": false,

          "targets": [

            {

              "expr": "node_load5{instance="10.0.20.25:9100"}",

              "format": "time_series",

              "intervalFactor": 1,

              "legendFormat": "{{instance}}",

              "refId": "A"

            }

          ],

          "thresholds": [],

          "timeFrom": null,

          "timeShift": null,

          "title": "5分鐘負載",

          "tooltip": {

            "shared": true,

            "sort": 0,

            "value_type": "individual"

          },

          "type": "graph",

          "xaxis": {

            "buckets": null,

            "mode": "time",

            "name": null,

            "show": true,

            "values": []

          },

          "yaxes": [

            {

              "format": "short",

              "label": null,

              "logBase": 1,

              "max": null,

              "min": null,

              "show": true

            },

            {

              "format": "short",

              "label": null,

              "logBase": 1,

              "max": null,

              "min": null,

              "show": true

            }

          ]

        }

      ],

      "repeat": null,

      "repeatIteration": null,

      "repeatRowId": null,

      "showTitle": false,

      "title": "Dashboard Row",

      "titleSize": "h6"

    }

  ],

  "schemaVersion": 14,

  "style": "dark",

  "tags": [],

  "templating": {

    "list": []

  },

  "time": {

    "from": "now-30m",

    "to": "now"

  },

  "timepicker": {

    "refresh_intervals": [

      "5s",

      "10s",

      "30s",

      "1m",

      "5m",

      "15m",

      "30m",

      "1h",

      "2h",

      "1d"

    ],

    "time_options": [

      "5m",

      "15m",

      "1h",

      "6h",

      "12h",

      "24h",

      "2d",

      "7d",

      "30d"

    ]

  },

  "timezone": "",

  "title": "test_dashboard",

  "version": 1

}

此外我們可以將這個模板文件導出作為備份,然後刪除這個模板。後續會通過http api來添加這個模板。

4、修改上面的這個json文件,修改後的如下:

注意標記紅色的第1、2行還有最後3行,都是新加了的內容。

{

  "dashboard":

{

  "annotations": {

    "list": [

      {

        "builtIn": 1,

        "datasource": "– Grafana –",

        "enable": true,

        "hide": true,

        "iconColor": "rgba(0, 211, 255, 1)",

        "name": "Annotations & Alerts",

        "type": "dashboard"

      }

    ]

  },

  "editable": true,

  "gnetId": null,

  "graphTooltip": 0,

  "hideControls": false,

  "id": null,

  "links": [],

  "rows": [

    {

      "collapse": false,

      "height": "250px",

      "panels": [

        {

          "aliasColors": {},

          "bars": false,

          "dashLength": 10,

          "dashes": false,

          "datasource": "prom25",

          "decimals": 2,

          "fill": 3,

          "id": 1,

          "legend": {

            "alignAsTable": true,

            "avg": false,

            "current": true,

            "max": true,

            "min": true,

            "show": true,

            "total": false,

            "values": true

          },

          "lines": true,

          "linewidth": 2,

          "links": [],

          "nullPointMode": "null",

          "percentage": false,

          "pointradius": 5,

          "points": false,

          "renderer": "flot",

          "seriesOverrides": [],

          "spaceLength": 10,

          "span": 12,

          "stack": false,

          "steppedLine": false,

          "targets": [

            {

              "expr": "node_load5{instance="10.0.20.25:9100"}",

              "format": "time_series",

              "intervalFactor": 1,

              "legendFormat": "{{instance}}",

              "refId": "A"

            }

          ],

          "thresholds": [],

          "timeFrom": null,

          "timeShift": null,

          "title": "5分鐘負載",

          "tooltip": {

            "shared": true,

            "sort": 0,

            "value_type": "individual"

          },

          "type": "graph",

          "xaxis": {

            "buckets": null,

            "mode": "time",

            "name": null,

            "show": true,

            "values": []

          },

          "yaxes": [

            {

              "format": "short",

              "label": null,

              "logBase": 1,

              "max": null,

              "min": null,

              "show": true

            },

            {

              "format": "short",

              "label": null,

              "logBase": 1,

              "max": null,

              "min": null,

              "show": true

            }

          ]

        }

      ],

      "repeat": null,

      "repeatIteration": null,

      "repeatRowId": null,

      "showTitle": false,

      "title": "Dashboard Row",

      "titleSize": "h6"

    }

  ],

  "schemaVersion": 14,

  "style": "dark",

  "tags": [],

  "templating": {

    "list": []

  },

  "time": {

    "from": "now-30m",

    "to": "now"

  },

  "timepicker": {

    "refresh_intervals": [

      "5s",

      "10s",

      "30s",

      "1m",

      "5m",

      "15m",

      "30m",

      "1h",

      "2h",

      "1d"

    ],

    "time_options": [

      "5m",

      "15m",

      "1h",

      "6h",

      "12h",

      "24h",

      "2d",

      "7d",

      "30d"

    ]

  },

  "timezone": "",

  "title": "test_dashboard",

  "version": 1

}

,

 "overwrite": true

}

5、使用chrome的插件restlet_client模擬POST提交操作

如下圖,關鍵點都用紅色框起來了。 BODY部分填的就是上面第4步的修改後的json內容。

如果返回值是200OK,則表示post提交成功了。然後去grafana介面查看下吧。沒啥問題的話,就可以將這個post請求弄出來了。

點擊上圖介面的右上角「save as」旁邊的小箭頭,點擊「copy as curl」,即可導出curl格式的命令明細。

我們可看下這個curl的內容,實際上變化的就是3個地方:

1、curl的header部分的認證欄位(用來區分屬於哪個grafana組織)

2、http的data部分,實際上就是我們的dashboard的全部內容。

3、dashboard的名稱。

6、後期

通過上面的幾個步驟,我們就可以再努力下,用python搞個web介面,傳一個grafana的組織,需要的主機IP即可完成添加。

【grafana里的組織和apikey存在對應關係。 對於http的data部分,實際上只要每次改成一個IP就是一個新的模板(咱DBA的機器,都是一個IP對應一個模板)】