LoginSignup
4
1

More than 3 years have passed since last update.

How to generate Grafana dashboard json from grafanalib

Last updated at Posted at 2019-10-29

grafanalibを使ってGraranaのダッシュボードを作る

ZabbixやPrometheus等を使っていると描画にGrafanaを使う機会が生まれる。
その際のダッシュボードはWebUIから操作することで簡単に作れるのだが、
同じような作業の場合、この単純作業が苦痛になる。
幸い、ダッシュボードの設定はJSON import/exportがある為、JSONで流し込めるよう
generatorを使って作って観ることにする

どんなツールを使うか

大きく2つのツールがあり、それらの解説についてはこちらに記載があるので
そちらをご覧頂ければと思う。

ここではgrafanalibを使ってより細かい値を作ろうとしたときのHow Toを記載する
残念ながらこちらの公式には非常に簡単な例しかなく、ダッシュボード本体の設定等がどうなっているのかよくわからない。

Annotationを追記してみる

#!/usr/bin/env python3
#  -*- coding: utf-8 -*-
from grafanalib import core


def _annotations(name):
    return core.Annotations(list=[{
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": True,
        "hide": True,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": name,
        "type": "dashboard"
    }])


def _row(title):
    return core.Row(panels=[
        core.Graph(
            title=title,
            dataSource='prometheus',
            targets=[
                core.Target(
                    expr=title,
                    legendFormat='{{namespace}}',
                ),
            ],
            yAxes=[
                core.YAxis(format=core.NO_FORMAT),
                core.YAxis(format=core.SHORT_FORMAT),
            ]
        )
    ])


dashboard = core.Dashboard(
    title='hogehoge',
    uid="XK5tCdAWk",
    annotations=_annotations('Annotations & Alerts'),
    rows=[
        _row('title')
    ],
).auto_panel_ids()

実行結果

{
  "__inputs": [],
  "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,
  "hideControls": false,
  "id": null,
  "links": [],
  "refresh": "10s",
  "rows": [
    {
      "collapse": false,
      "editable": true,
      "height": "250px",
      "panels": [
        {
          "aliasColors": {},
          "bars": false,
          "datasource": "prometheus",
          "description": null,
          "editable": true,
          "error": false,
          "fill": 1,
          "grid": {
            "threshold1": null,
            "threshold1Color": "rgba(216, 200, 27, 0.27)",
            "threshold2": null,
            "threshold2Color": "rgba(234, 112, 112, 0.22)"
          },
          "id": 1,
          "isNew": true,
          "legend": {
            "alignAsTable": false,
            "avg": false,
            "current": false,
            "hideEmpty": false,
            "hideZero": false,
            "max": false,
            "min": false,
            "rightSide": false,
            "show": true,
            "sideWidth": null,
            "sort": null,
            "sortDesc": false,
            "total": false,
            "values": false
          },
          "lines": true,
          "linewidth": 2,
          "links": [],
          "minSpan": null,
          "nullPointMode": "connected",
          "percentage": false,
          "pointradius": 5,
          "points": false,
          "renderer": "flot",
          "repeat": null,
          "seriesOverrides": [],
          "span": 12,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "datasource": "",
              "expr": "title",
              "format": "time_series",
              "instant": false,
              "interval": "",
              "intervalFactor": 2,
              "legendFormat": "{{namespace}}",
              "metric": "",
              "refId": "",
              "step": 10,
              "target": ""
            }
          ],
          "timeFrom": null,
          "timeShift": null,
          "title": "title",
          "tooltip": {
            "msResolution": true,
            "shared": true,
            "sort": 0,
            "value_type": "cumulative"
          },
          "transparent": false,
          "type": "graph",
          "xaxis": {
            "show": true
          },
          "yaxes": [
            {
              "decimals": null,
              "format": "none",
              "label": null,
              "logBase": 1,
              "max": null,
              "min": 0,
              "show": true
            },
            {
              "decimals": null,
              "format": "short",
              "label": null,
              "logBase": 1,
              "max": null,
              "min": 0,
              "show": true
            }
          ]
        }
      ],
      "repeat": null,
      "showTitle": false,
      "title": "New row"
    }
  ],
  "schemaVersion": 12,
  "sharedCrosshair": false,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-1h",
    "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": "utc",
  "title": "hogehoge",
  "uid": "XK5tCdAWk"
}

grafanalibは要するにGrafanaのJSON specに沿って値を埋め込んでいるだけなので
たいていはここを読めば定義できそうである。
annotation等のクラスはどうすればいいかというとcore.pyを読めばだいたい理解可能。
これでrowだけでなく色々な変数を埋め込めそうだ。

追記

  • versionはGrafanaに保存されるjsonファイルのversionなので固定化すると競合してしまうから記載しない方が良い
  • 困ったことにGrafana 6.xを使っていたら rows = の所がnestしてpanels = ではなくそのまま panels = になっていた。

    • 取り込んではくれるが取り込んだ時点でコンバートが掛かってしまうのでimportしたものをexportして保存しようとすると差分が発生してしまう
  • 対抗というか公式が出しているjsonnet/grafonnetでも rowはschema version 16以前の書式だぜ!って書いてあった。。。

どうするかな。。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1