Grafonnet の使い方

このページには Grafonnet の使い方について書いてあります。

Grafonnet とは? #

Grafonnet は、Grafana ダッシュボードを定義する JSON を生成するためのツールです。

Grafana のダッシュボードはすべて JSON 形式で定義されています。 Grafonnet は、Grafana のダッシュボードの JSON を生成するための Jsonnet の関数を提供するライブラリーです。

Grafonnet を使うモチベーションは ZLab の Yoshida さんの発表「Grafana Dashboards as Code」 によくまとまっていますのでそちらを参照してください。

Grafonnet の実行環境準備 #

Grafonnet の実行環境は 公式ドキュメントの Getting Started に書いてあるとおり Jsonnet が動く環境を用意し、Grafonnet をダウンロードするだけで作れます。

ここでは Docker で実行環境を作ります。 Dockerfile で書くと下記の4行のみで環境が作れます。

FROM golang:1.15.5-buster
RUN go get github.com/google/go-jsonnet/cmd/jsonnet
RUN git clone https://github.com/grafana/grafonnet-lib.git
ENTRYPOINT [ "jsonnet", "-J", "grafonnet-lib"]

あとは Docker の -v オプションでローカルにある Grafonnet 用の Jsonnet ファイルをマウントしてそのファイルを指定して実行すればよいです。

$ docker build -t grafonnet .
$ docker run -it --rm -v $PWD/grafonnet-templates:/go/grafonnet-templates grafonnet grafonnet-templates/sample.jsonnet

コンパイルした JSON ファイルは標準出力に出力されるので、パイプを利用してファイルに出力すればよいです。

Grafonnet 用の Jsonnet ファイルの書き方 #

Grafonnet に関するドキュメントは公式ドキュメント以外は世の中にあまり多くはないのが現状です。

公式ドキュメントとして参考になるものは次のようなものがあります。

サンプルコード #

個人的にこんな風に Grafonnet のコードを書けばわかりやすいんじゃないかと思っているサンプルコードを紹介します。 なお、このサンプルは Prometheus の Node Exporter のメトリクスを使うこと前提とした Jsonnet ファイルです。

参考までにパネルのサンプルを こちら に用意しています。

// Load the Grafonnet library
local grafana = import 'grafonnet/grafana.libsonnet';

// Define panels
local cpuUsage = 
    grafana.graphPanel.new(
        title='CPU usage',
        format='percent',
        stack=true,
    )
    .addTarget(
        grafana.prometheus.target('sum(rate(node_cpu_seconds_total{instance="$instance", mode!="idle"}[$__interval])) by (mode) * 100'),
    );

local memoryUsage = 
    grafana.graphPanel.new(
        title='Memory usage',
        format='bytes',
    )
    .addTargets([
        grafana.prometheus.target('node_memory_MemTotal_bytes{instance="$instance"}', legendFormat='Available'),
        grafana.prometheus.target('node_memory_MemTotal_bytes{instance="$instance"} - node_memory_MemAvailable_bytes{instance="$instance"}', legendFormat='Used'),
    ]);

// Create a dashboard using defined panels above
grafana.dashboard.new(
    title='Sample Dashboard',
    editable=true
)
.addTemplate(
    grafana.template.new(
        'instance',
        'Prometheus',
        'label_values(node_uname_info, instance)',
        label='Instance',
        refresh='time',
    )
)
.addPanels([
    cpuUsage + {gridPos: {h: 8, w: 8, x: 0, y: 0}},
    memoryUsage + {gridPos: {h: 8, w: 8, x: 8, y: 0}},
])

“Load the Grafonnet library” とコメントしているところは、Grafonnet 用のライブラリーを読み込んでいるだけです。 Grafana 用のダッシュボードやパネル作成用のクラスなどはこの grafana という変数から呼び出します。

“Define panels” とコメントしているところで、ダッシュボードに載せるパネルを定義していきます。 上記のように複数パネルを配置する場合はパネルごとに定義します。 なお、この例では Prometheus を参照しているため PromQL でクエリを書いています。

“Create a dashboard using defined panels above” とコメントしてあるところで、grafana.dashboard.new でダッシュボードを作成し、addPanels でそれまでに定義したパネルを配置していきます。 また、Grafana のテンプレート (変数) を定義する場合は、.addTemplate で定義します。 この例ではパネルで表示するインスタンスを指定するためのテンプレートを定義しています。