はじめに
監視サービスでアラートが鳴った場合,それは閾値を超えた異常値が検知されているので,すぐに対応が必要だけど,もしかしたら通常時にも何か起きてるかもしれないし,通常時の傾向が特定のリリース以降で変わってしまっているかもしれないし,監視設定が漏れているかもしれない.逆にリソースが余りすぎていて過剰な投資をしてしまっているかもしれない.だからこそ,日々モニタリングすることは重要で,そんなモニタリングに絶対に欠かせない機能は「ダッシュボード」だと思ってる.
今回は mkr dashboards
コマンドを使って Mackerel のカスタムダッシュボードを生成した話をまとめてみようと思う.
カスタムダッシュボードとは?
Mackerel には「カスタムダッシュボード」という機能がある.ただそんなに複雑なものではなくて,一言で言ってしまうと「Markdown 記法が使える汎用的なテキストエリア」という感じ.だから,Zabbix Screen や AWS CloudWatch Dashboard とは違って,ダッシュボードを作る場合,Mackerel のメトリックグラフから iframe をコピーして,ダッシュボードに貼り付ける作業を繰り返す必要がある.結構大変!
mkr dashboards
コマンドとは?
そこで mkr dashboards
を使って自動化することを考えた.
ダッシュボードの期待値を YAML に定義して,mkr dashboards
コマンドを実行することで自動でダッシュボードを生成することができる.さらに YAML を GitHub にコミットすることで,バージョン管理をすることができる.便利!
もしかしたら mkr monitors
コマンドと似てる?と思った人もいるかもしれないけど,残念ながら push / pull / diff
といったサブコマンドは用意されていなくて,実際には mkr dashboards generate
しかない.ダッシュボードの反映を抑制する --print
オプションはあるけど,デフォルトの動作だと,強制的にダッシュボードを反映するので「generate
だから試してみよう!」みたいに気軽に実行するとアレなので注意が必要だよ!
# ダッシュボードを反映する $ mkr dashboards generate xxx.yml # Markdown を標準出力に表示する $ mkr dashboards generate xxx.yml --print
mkr dashboards
コマンドで生成できるダッシュボードの種類
ドキュメントにも書いてある通り,mkr dashboards
コマンドを使うと,2種類のダッシュボードを作ることができる.
名前が直感的ではなくて微妙な気がするけど,簡単に覚えるなら「ホストごとのダッシュボード」と「ロールごとのダッシュボード」と覚えておけば良さそう.
- ホストグラフ(YAML では
host_graphs
で定義する)- ホストごとに指定したグラフ(例えば loadavg5 など)を表示する
- 個別グラフ指定(YAML では
graphs
で定義する)- ロールごとに指定したグラフ(例えば loadavg5 など)を表示する
- その他として,サービスメトリックや式グラフを表示することもできる
詳細な YAML の項目説明は公式ドキュメントに書いてある.
ロールダッシュボードを作った
今回 mkr dashboards
コマンドを使って,ロールごとに重要な監視項目をモニタリングするためのダッシュボード(今回は "ロールダッシュボード" と呼ぶ)を作った.
今回は「ロールダッシュボード (web)」を例にして,YAML を作るのに工夫したところを書く.
- ロールダッシュボード (web)
- ロールダッシュボード (db)
- ロールダッシュボード (aggregator)
- などなど...
工夫点 1 : 期間ごとに short と long に分割した
Mackerel のダッシュボードでは,Zabbix Screen や AWS CloudWatch で提供されているような期間選択の機能がないという欠点がある.よって,期間ごとにグラフを配置していく必要がある.
最初に「6種類の期間」と「6種類の監視項目」を YAML に書いてみた.単純計算で36個のグラフをダッシュボードに配置することができた.ただ予想通り,グラフの描画があまりにも遅く,全てのグラフが描画されるまでに30秒程度掛かっていた.これじゃダメだ!運用に耐えない!
- 期間
- 1h
- 1d
- 1w
- 1mo
- 3mo
- 6mo
- 監視項目
- loadavg5
- cpu.{user,iowait,system}
- memory.used
- custom.nginx.requests.requests
- custom.php-fpm.processes.total_processes
- custom.fluentd.buffer_total_queued_size.out_nginx_access
どう工夫したかと言うと,期間を分割してダッシュボードを2個にした.これでグラフ数を半分にすることができて,描画のパフォーマンスも改善できた.
- short(一時的にスパイクしたときなど,短期的な傾向を見るときに使う)
- 1h
- 1d
- 1w
- long(中長期的に傾向を見るときに使う)
- 1mo
- 3mo
- 6mo
工夫点 2 : headline に期間を記載した
グラフが期間ごとに3個並んでいると,一瞬「このグラフの期間ってなんだっけ?」とわからなくなることがある.特にアプリケーション開発者など,たまにダッシュボードを見るメンバーのことを考えると,明記しておきたいと思った.ただ mkr dashboards
コマンドではテーブルに任意の文字を書き出すことができないため,headline
に書いた.
graphs: (中略) - headline: loadavg5 ( 1h / 1d / 1w ) (中略)
これで少しは改善できた.
工夫点 3 : システムメトリック名に記号が使われていてもそのまま YAML に書く
例えば,システムメトリックにある cpu.{user,iowait,system}
のグラフを描画したいと思ったときに,管理画面から取得できる iframe のタグを見ると以下のようになっていて,手動でカスタムダッシュボードを作る場合は当然 URL エンコードしたまま貼り付ける必要がある.ただ YAML の graph_name
に書くときに cpu.%7Buser%2Ciowait%2Csystem%7D
と書くのは嫌だなーと思っていた.
<iframe src="https://mackerel.io/embed/orgs/my-org/services/my-service/web?graph=cpu.%7Buser%2Ciowait%2Csystem%7D&stacked=true&simplified=false&period=1h" height="200" width="400" frameborder="0"></iframe>
実際に試したら問題なくて,そのまま cpu.{user,iowait,system}
と書くことができた.良かった.ちなみにグラフを「積み上げ」で表示する場合は stacked: true
と書く必要がある(デフォルトは false).
graphs: - headline: cpu.{user,iowait,system} ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: cpu.{user,iowait,system} stacked: true period: 1h (中略)
最終的にできた YAML の例 : web_short.yml
こんな感じになった.うーん記述量が多いなぁ...!と思う.
config_version: 0.9 url_path: web_short title: web_short format: iframe graphs: - headline: loadavg5 ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: loadavg5 period: 1h - service_name: my-service role_name: web graph_name: loadavg5 period: 1d - service_name: my-service role_name: web graph_name: loadavg5 period: 1w - headline: cpu.{user,iowait,system} ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: cpu.{user,iowait,system} stacked: true period: 1h - service_name: my-service role_name: web graph_name: cpu.{user,iowait,system} stacked: true period: 1d - service_name: my-service role_name: web graph_name: cpu.{user,iowait,system} stacked: true period: 1w - headline: memory.used ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: memory.used period: 1h - service_name: my-service role_name: web graph_name: memory.used period: 1d - service_name: my-service role_name: web graph_name: memory.used period: 1w - headline: custom.nginx.requests.requests ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: custom.nginx.requests.requests period: 1h - service_name: my-service role_name: web graph_name: custom.nginx.requests.requests period: 1d - service_name: my-service role_name: web graph_name: custom.nginx.requests.requests period: 1w - headline: custom.php-fpm.processes.total_processes ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: custom.php-fpm.processes.total_processes period: 1h - service_name: my-service role_name: web graph_name: custom.php-fpm.processes.total_processes period: 1d - service_name: my-service role_name: web graph_name: custom.php-fpm.processes.total_processes period: 1w - headline: custom.fluentd.buffer_total_queued_size.out_nginx_access ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: custom.fluentd.buffer_total_queued_size.out_nginx_access period: 1h - service_name: my-service role_name: web graph_name: custom.fluentd.buffer_total_queued_size.out_nginx_access period: 1d - service_name: my-service role_name: web graph_name: custom.fluentd.buffer_total_queued_size.out_nginx_access period: 1w
最終的にできたダッシュボードの例
こんな感じになった!
mkr dashboards
コマンドの進化に期待すること
次に mkr dashboards
コマンドで改善してもらえると最高に便利なのに!という個人的な期待を書いてみたいと思う.
期待 1 : periods
をサポートして欲しい
現在の仕様だと,期間 period
は単一項目でしか定義できないため,上に載せた例のように YAML が無駄に大きくなってしまう問題がある.そこで host_ids
や graph_names
と同様に periods
として配列形式で定義したい.今回の例で言うと,以下のように period
のためだけに graph_def
を3回繰り返して定義する必要があった.
graphs: - headline: loadavg5 ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: loadavg5 period: 1h - service_name: my-service role_name: web graph_name: loadavg5 period: 1d - service_name: my-service role_name: web graph_name: loadavg5 period: 1w
もし periods
が使えれば,以下のようにスッキリと定義することができて最高なのでは?と思う.もっと言うと column_count
の値も自動判別してくれるとさらに嬉しい.
graphs: - headline: loadavg5 ( 1h / 1d / 1w ) column_count: 3 graph_def: - service_name: my-service role_name: web graph_name: loadavg5 periods: - 1h - 1d - 1w
期待 2 : mkr dashboards
コマンドで任意のテキストをサポートして欲しい
ダッシュボードに任意のテキストを書くことができると表現の幅がグッと広がるし,インフラエンジニアの暗黙知のようなものを補足することもできるし便利だと思ってる.手動でダッシュボードを作るなら,書けば良いだけなんだけど,mkr dashboards
コマンドだとできない.ただ mkr dashboards
コマンドでダッシュボードを生成した後に手動で書き換える的なツライ運用もしたくないから,サポートして欲しい.
ちなみにダッシュボードに任意のテキストを書ける機能は珍しくなく,Zabbix Screen なら「プレーンテキスト」として書けるし,AWS CloudWatch なら「テキストウィンドウ」に書ける.Kibana にも「Markdown Widget」がある.個人的にもよく使っている.
期待 3 : filesystem をロールで見れるようにして欲しい
システムメトリックの filesystem
グラフはホスト画面でしか見れず,ロールだと見れない.ロールごとの filesystem
グラフをダッシュボードに表示したいと思っていて,見れるようにして欲しい.
期待 4 : サブコマンドを mkr monitors
コマンドと合わせて欲しい
個人的に mkr dashboards generate
コマンドでダッシュボードが更新されてしまうのは少し違和感があるのと,ある意味ユースケースは似ている mkr monitors
コマンドとサブコマンドが違うのも気になっている.mkr dashboards generate
コマンドは残すとして,例えば以下のようなサブコマンドはどうだろう?と考えていた.まぁ現実的に考えると,pull
と diff
は難しそうな気がするので,せめて generate
と push
になってくれると良いのかもしれない.
mkr dashboards generate
- 標準出力に表示する
mkr dashboards push
- Mackerel 管理画面に反映する
mkr dashboards pull
- Mackerel 管理画面からエクスポートする
mkr dashboards diff
- Mackerel 管理画面と YAML を比較する
次世代ダッシュボードに期待すること
本音で言うと Mackerel のダッシュボードに期間選択の機能がないことに困っている.Zabbix Screen なら 1h / 2h / 3h / 6h / 12h / 1d / ... / 1y
と選択できるし,AWS CloudWatch でも任意の期間(14日以内)を選択することができる.ちなみに Mackerel もサービス画面なら 30min / 1h / 6h / 1d / 1W / 1M / 1Y
で選べるのに,なぜかダッシュボードでは選べず「Markdown 記法が使える汎用的なテキストエリア」になってしまっている.
急にスパイクしたときだったり,過去の傾向を調査するときだったり,特定の期間で複数のグラフを見るというシチュエーションは多いのではないかと思う.少なくとも僕はよくあって,Zabbix Screen をよく使っている(まぁ Zabbix だとロールでグラフを見れない欠点はあるんだけど).次世代ダッシュボードの可能性があるなら是非検討してもらいたい.
実は先週の Mackerel Meetup に参加したときに「どうダッシュボードを使ってますか?」と質問したら「期間ごとに並べてますねー」という回答だったけど「確かに期間指定で絞り込めたら便利ですねー」という声もあった.
まとめ
今回は Mackerel のダッシュボードを便利に運用したいと思って mkr dashboards
コマンドを頑張って使ってみた!現在は計6個のロールダッシュボードを運用していて,結構便利に使えているので,満足している.
最近 Mackerel User Group の Slack に JOIN したので「皆さんはダッシュボードをどうやって活用してますか?」みたいな雑談をしてみたいなー!と思ったりしている(発言するのちょっと恥ずかしい).もっと良い活用方法があるなら是非聞いてみたい.
関連記事
「ホストグラフ」と「個別グラフ指定」のサンプルが載っていて,YAML とダッシュボードの比較が凄くわかりやすかった.
mkr monitors
コマンドを使って監視ルールをバージョン管理 & CI できるようにした話を最近書いた.
Mackerel を本格的に導入する前に Zabbix を使って每日楽しくモニタリングをしていた話を社内勉強会でしたときの資料も以前公開している.