prometheusとgrafanaを入れたみたが、どうグラフとか出すといいのか?

# はじめに
prometheusでこんなmetricsとって、grafanaでこんなquery指定すると、こう見えるよの紹介。
始めたばかりで環境準備できたはいいが、ぱぱっとそれっぽいグラフとか出したい人向け。
とりまサーバの状態がいろいろ見えるダッシュボードができるまでの説明を詳しめにします。

# notes
- 環境前提にとりま以下入ってること
    - (今回はubuntu on EC2 1つにごちゃ入れした)
    - prometheus 1.8.2(2.0でないが同様かと)
        - [First steps](https://prometheus.io/docs/introduction/first_steps/)
        - [Getting started](https://prometheus.io/docs/prometheus/latest/getting_started/)
    - grafana 4.6.2、prometheusをdata source登録済み
        - [Installing Grafana](http://docs.grafana.org/installation/)
        - [Creating a Prometheus data source](https://prometheus.io/docs/visualization/grafana/)
    - node_exporter 0.15.1
        - (↑のFirst stepsに手順あり)


# サーバの状態いろいろ見えるの
「notes」の準備ができてれば、以下はポチポチすればすぐできます。

![96529008-7966-4427-a322-348079d2eaea.png](https://qiita-image-store.s3.amazonaws.com/0/26677/94db7f8d-6c0a-afd6-afb1-6100dbbbdb40.png)

なおダッシュボードの実例として、[Grafana LabでprometheusのDashboard](https://grafana.com/dashboards?dataSource=prometheus)を探すのがよいと思います。 スクショもあってイメージしやすく、監視対象のがあるとだいたいそのまま使えます。

また[Grafana Plugins](https://grafana.com/plugins)でdata sourceやpanelなども増やせます。

ここではprometheusが動いてるサーバ上で同じくnode_exporterを動かしているので、

0. [LabsのPrometheus system](https://grafana.com/dashboards/159)で`Copy ID to Clipboard`
1. 自分のgrafanaをブラウザで開く
2. adminログイン
3. 左上メニュー-> `Dashboards` -> `Import`
4. `Grafana.com Dashboard`にIDをペースト -> `Load`
5. `Options`のData sourceを自分で足したprometheus選択
6. `Import`で↑のができます

参考:[Importing a dashboard](http://docs.grafana.org/reference/export_import/#importing-a-dashboard)

# どう動いているか?

中身の理解のため、`Memory Distribution`のグラフに注目してみます。
ダッシュボード上グラフタイトルをクリック->`View`でそのグラフだけ拡大でき、さらに`Edit`で以下prometheusのqueryが表示されます。

![afabbe6c-f8c6-4e59-8aca-be6e85ec6f41.png](https://qiita-image-store.s3.amazonaws.com/0/26677/b720d041-0304-7a7e-8c3f-44d4e5cd69c1.png)

このグラフは4つのqueryで1つのグラフを生成しています。
ここでB行`node_memory_MemFree` metricに注目すると、prometheus上では、

![37d0cdd6-f4c9-447e-b241-d892ca675fd5.png](https://qiita-image-store.s3.amazonaws.com/0/26677/81c67740-b908-d7f7-2305-4093010ac9dd.png)

1つのElement(metric name +label) vs. Value情報が保管されています。
prometheus上の画面では`hostname`だ`job`だとlabelが付与されていますが、これはexporter側でなく、prometheus側で付与されたものとなります。

今回は監視しているnode_exporterが1つですが、もし複数のEC2などを監視する場合、同一metric nameでhostnameなど別labelのmetricが複数できます。
するとGrafana上`node_memory_MemFree{$tag="$host"}`というqueryになっていることに意味がでてきます。`$tag="$host"`はGrafana側の[templating](http://docs.grafana.org/reference/templating/)という機能でサーバが増えてもその分のqueryを自動生成してくれるので、監視対象が増えてもダッシュボードそのものは編集不要となります。

また実際にはnode_exporter側の生のレスポンスはcurlで確認できるので、

```bash
$ curl localhost:9100/metrics
...
# HELP node_memory_MemFree Memory information field MemFree. (← metrics説明分)
# TYPE node_memory_MemFree gauge (← metrics type)
node_memory_MemFree 5.35724032e+08 (← metrics名と現在値) 
...

```

とnode_exporterにrequestされた瞬間のmem freeの値を返してるだけです。

metrics typeとはCounterやGaugeのことで[公式解説](https://prometheus.io/docs/concepts/metric_types/)を読むとわかりやすいです。
要はmem free値など現在の値をそのまま代入されるのがGaugeでhttp requestなど単位時間あたりを取得して先の値に加算して欲しい場合などはCounterを使ったり、とmetricsのとり方による違いがあります。

なお、metricsに複数labelがある場合について、先のcurlの結果のfilesystem freeに注目すると、

``` bash

# HELP node_filesystem_files_free Filesystem total free file nodes.
# TYPE node_filesystem_files_free gauge
node_filesystem_files_free{device="/dev/xvda1",fstype="ext4",mountpoint="/"} 809613
node_filesystem_files_free{device="lxcfs",fstype="fuse.lxcfs",mountpoint="/var/lib/lxcfs"} 0
node_filesystem_files_free{device="tmpfs",fstype="tmpfs",mountpoint="/run"} 255383
node_filesystem_files_free{device="tmpfs",fstype="tmpfs",mountpoint="/run/lock"} 255852
node_filesystem_files_free{device="tmpfs",fstype="tmpfs",mountpoint="/run/user/1000"} 255851

```

のように{}で囲まれて`device`や`mountpoint`などlabelが記載されます。
もしGrafana上で`node_filesystem_files_free`というqueryだけ指定した場合は5つのmetricsがhitするので、それらは展開されて5つ線が表示されたグラフが生成されます。

# file system freeのグラフを追加してみる
空いているダッシュボード末尾右下に`Filesystem Free`パネルを足してみる。

![b1f7a4fe-a20a-4923-a6f0-ff386e71f6b7.png](https://qiita-image-store.s3.amazonaws.com/0/26677/55a4e3a4-e509-10c4-5e79-099f12c43b33.png)

0. graphパネルを追加
    1. grafana画面で、左側面にマウスを持っていく
    2. `add panel`
    3. `graph`
0. パネル設定
    1. パネルの`edit`で編集画面へ
    2. `General`タブ ![25a607da-d3ec-4213-a06a-499ce9ccd06c.png](https://qiita-image-store.s3.amazonaws.com/0/26677/f52bdc4b-237d-105e-d4ca-72626fd64ba0.png)
    3. `Metrics`タブ ![5a6f62d6-e13e-426e-aa3e-22ae24639844.png](https://qiita-image-store.s3.amazonaws.com/0/26677/30e0dcf7-0399-c612-2160-50bdf3fc0e15.png)
    4. `Axes`タブ ![6b728013-4beb-4d48-9399-3443091b8471.png](https://qiita-image-store.s3.amazonaws.com/0/26677/dbab084f-f195-18b4-09bc-11283b72bbea.png)
    5. `Legend`タブ ![0ee8a2fc-e597-4ca7-a80e-47ec3ef56c44.png](https://qiita-image-store.s3.amazonaws.com/0/26677/9adddcb8-526c-0cf5-e259-f637547850a9.png)
    6. 終わったら右上の`Back to dashboard`
    7. で最後にCtrl-sでダッシュボードの保存を忘れずに


# サーバが増えたら自動でダッシュボードも増やすには?

前述の通りダッシュボード側はtemplating機能ですでに準備できているため、

0. 増えたサーバにnode_exporterが導入済み
0. 増えたサーバのIP:portをprometheusがtargetとして取得

という工程がさらに必要です。

1つ目はchefなりprovisioning段階でいい感じに自動で入れてもらうとして、2つ目は[Prometheusのec2 service discoveryを試す - 技術的なメモというか、忘却録](http://clavier.hatenablog.com/entry/2017/02/12/103505)+特定のtagをaws上でつけておくと、サーバができれば自動でこの監視ダッシュボードができるようになります(左上のHostで選択)。(prometheus.ymlのtargesにIP:port listを手書きでも増えはする)

# おわりに

prometheusは割りと「で、どう使うといいの?」な資料がまだまだないと周りからよく聞くのでとりま紹介系記事を書いてみました。というか本記事はgrafanaでどうグラフを作るかにだいぶ寄ってはいますね... 

後述の自作exporterの話もありますが、どういうqueryをgrafanaから叩けばいいか?は慣れるまで結構難しいです。それには実例をあれこれ眺めてquery functionの使い方など理解を進めると良いので、前述のGrafana Labsのダッシュボードサンプル入れてみてその中身を確認していくのがオススメです。

# おまけポエム : prometheusでの監視設計

筆がのったのでついでに書きますが、流れとして、

0. どう通知が欲しいか? or ダッシュボードで状況確認したいか?
0. prometheus上どういうmetricsが保管されてるべきか?
0. どう対象をexporterから監視できるか?
0. 実装からprometheus alert rule or grafanaからのqueryをどうするか?

と組み立てていきますが、custom exporterを作る場合の制約としてよく気にするのは、

- metrics設計
    - 時系列DBとして時間vs.数値に落とし込めるか?
    - 連続しているか?
    - 監視対象の可変箇所をlabelでうまく表現できるか?
    - (sd観点でアラート/グラフ設定を自動で対象増えたら増えるor簡単に変更できるか?)
- 監視先の叩き方
    - exporterからアクセスする口はあるか?(NWやapi仕様など)
    - どのくらいこまめに監視先を叩いて大丈夫か?

あたりかと思います。
まずは[公式writing exporters](https://prometheus.io/docs/instrumenting/writing_exporters/)を読めという話もあります。

prometheusは特に[query function](https://prometheus.io/docs/prometheus/latest/querying/functions/)が豊富なのでmetricsで取るべき値は可能な限り素朴なものにしておき、あとで加工するようにした方がよいかと思います。

また、ミドルウェア監視用途では既存のexporterをいかに使うか?(自分でexporter作らない)という文脈が強く、あまりcustom exporterを作ろうとはならないと思います。

ただ、exporterを自作することに熟れてくると、あるあるシステム構成だけでなく、自社なり独自サービスの監視まで幅を広げられます。
実際ちょっとしたスクレイピングをするbatchを書く程度の手間で作れるので一度作れば結構使いまわしができます。
例えばpythonなら[client_python](https://github.com/prometheus/client_python)のようにある程度の言語でlibraryは準備されてるので。

もっともサービスの謎管理画面など作る際に監視からも叩けるapiなど準備する必要がありますが。そこはサービスとしてマイクロサービス的な組み方であれば、prometheus/alertmaanger/各exporter/grafanaそれぞれと組み合わせるのに相性がよいと思います。

ま、なにはともあれ「おわりに」でも言及した「grafana labでdashbordのサンプルからqueryどうするといいかを漁るとよい」という話と同様、既存exporterコードを写経したりするのが理解を深めるには良さそうです。

以上。