どうも、かっぱです。
追記
Grafana
を手動でポチポチがかったるそうだったので Scripted-dashboard
を試してみた。
はじめに
以前に td-agent
の monitor_agent
を利用してこんなことをやっていたことを記事をツイートして頂いたようでして...
そっか〜 / “sinatra を使って td-agent(fluentd) のバッファの状態をモニタリングするダッシュボードを作ってみた - ようへいの日々精進 XP” http://t.co/GlfffnJTKI
— kenjiskywalker (@kenjiskywalker) 2014, 5月 29
汗...
お、td-monitoring の競合だ! / “sinatra を使って td-agent(fluentd) のバッファの状態をモニタリングするダッシュボードを作ってみた - ようへいの日々精進 XP” http://t.co/KbxQBJFFMn
— そのっつ (SEO Naotoshi) (@sonots) 2014, 5月 29
決して競合とかになろうとか思ったわけではない(笑)のだけども、ツイート頂いたことに感謝しつつ、あまりの不出来さに恥ずかしくなりながらも、次期バージョンwwに向けて Ruby
や td-agent
の勉強のつもりで取得出来る情報を Graphite と Grafana で可視化してみた。
尚、ちゃんとモニタリングしたい場合にはTreasure Agent Monitoring Serviceを使うと良いと思います!
monitor_agent についておさらい
monitor_agent は何をするのか?
上記を参考にすると...
HTTP
経由でJSON
形式の内部メトリックを取得できる監視エージェント24220
ポートでListen
するLTSV
形式でも情報を取得することが出来る
どんな情報が取得出来るのか?
- 各ホストで稼働している
td-agent
orfluentd
のプラグイン情報 - 各
output
プラグインのretry_count
/buffer_total_queued_size
/buffer_queue_length
- 下記の
td_monitor_agent
はemit_count
も合わせて取得出来る
設定
以下を td-agent.conf
に追加して td-agent
を再起動するだけ。
<source> type monitor_agent bind 0.0.0.0 port 24220 </source>
取得出来る情報
以下のように HTTP
リクエストを投げると...
curl -s http://${TD_AGENT_HOST}:24220/api/plugins.json | jq .
/api/plugin.json
でアクセスすると以下のように JSON
でレスポンスが返ってくる。
{ "plugins": [ { "config": { "port": "24220", "bind": "0.0.0.0", "type": "monitor_agent" }, "output_plugin": false, "type": "monitor_agent", "plugin_id": "object:3f9bf86637c0" }, { "config": { "tag": "apache.access", "path": "/var/log/httpd/access_log", "format": "apache", "type": "tail" }, "output_plugin": false, "type": "tail", "plugin_id": "object:3f9bf72eedd4" },
/api/plugin
でアクセスすると以下のように LTSV
でレスポンスが返ってくる。
plugin_id:object:3f9bf86637c0 type:monitor_agent output_plugin:false plugin_id:object:3f9bf72eedd4 type:tail output_plugin:false plugin_id:object:3f9bf72f09b8 type:copy output_plugin:true plugin_id:object:3f9bf72f0508 type:stdout output_plugin:true plugin_id:object:3f9bf72f0080 type:file output_plugin:true buffer_queue_length:0 buffer_total_queued_size:2384070 retry_count:0 plugin_id:object:3f9bf731bcf8 type:file output_plugin:true buffer_queue_length:0 buffer_total_queued_size:2384070 retry_count:0 plugin_id:object:3f9bf731ae48 type:s3 output_plugin:true buffer_queue_length:0 buffer_total_queued_size:13183110 retry_count:0
Tresure Data が提供するモニタリングサービスについて
現時点ではベータ版となっているようだが Tresure Data がモニタリングサービスを提供している。
以下のようにホストのリソース情報も確認することが出来る。
設定は monitor_agent
と同様 td-agent.conf
に以下を追加してプロセスを再起動するだけで監視が開始される。(※apikey
は事前にダッシュボードで取得しておく必要がある)
<source> type td_monitor_agent apikey xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx instance_id xxxxxxx disable_node_info true </source>
disable_node_info
を true
にしておくとホストのリソース情報以外の情報を送信する(デフォルトは false
になっている)。また、instance_id
を指定しない場合には td-agent.conf
のパスが表示されるようなので必要に応じて instance_id
は設定しておいた方がたくさんのホストを管理する場合には良いかと思われる。
詳細については...
- Treasure Agent Monitoring Service (ベータ)
- treasure-data/fluent-plugin-td-monitoring
- Treasure Agent MonitoringをProduction環境で使い始めた件
を見る。
で、どうするの?
こんな感じで...
各処理をどの位の粒度でメソッド化すれば良いのかも解らず、変数のスコープについてもシェルスクリプト的な使い方になってしまっているので突っ込みどころ満載。
大きな壁
monitor_agent
は JSON
や LTSV
で返ってくることは解ったが、そのレスポンスからプラグイン毎で retry_count
/ buffer_total_queued_size
/ buffer_queue_length
を取得する(JSON
をパースする)のが(自分にとって)至難の技であることは間違い無かったが試行錯誤の上で以下のようにした。
返ってきた JSON
の plugin
に含まれる数(size
メソッド)をプラグインの数として、そのプラグイン数分(実際には配列は 0
から始まるので取得したプラグイン数からマイナス 1
をする)のループ処理で JSON
からプラグイン毎の必要な値を取得した。
Graphite へのメトリクスを投げる
これは意外に簡単だった。幾つか Gem
が存在する中で以下の Gem
を利用した。
require 'graphite-api'
しておいて以下のようなメソッドで処理するようにした。
def post_graphite(host, type, rtc, bql, btqs) client = GraphiteAPI.new( graphite: $graphite_host ) client.metrics( "#{host}.#{type}.retry_count" => rtc, "#{host}.#{type}.buffer_queue_length" => bql, "#{host}.#{type}.buffer_total_queued_size" => btqs ) end
Graphite
が .
ピリオドをメトリクスパスの区切りとして利用する為 host
という変数は .
を -
に変換する処理を行っている。
実際に Graphite
には以下のように登録される。
Grafana だと...
以下のような感じになる。
ホストが増えてくると手動でポチポチするのが耐えられなくなると思われる...(そこで Grafana
の Scripted-dashboardsの出番だったりするのかな...)
最後に
JSON
をパースして結果をどうこうするという勉強にはなったが、もっと効率とか見栄え、メンテナンスし易い書き方を模索したい