fluentdのCPU使用率をPrometheus, Grafanaでモニタリングしたい
fluentdはRubyで実装されていることもあり複数CPUを使えないので、トラフィックが増えてきた場合などはポートを分けて複数プロセスで起動することが一般的です。
なのでマシンごとのCPU使用率を見てもfluentdの状況がどうなのか判断することは難しいです。
ちなみにJavaだとそういうことをする必要がないしJMXもあるのでfluentdが特殊なミドルウェアなのかなという気がします。
fluentd以外でユースケースを思いつかない。
そこでfluentdのプロセスごとのCPU使用率をモニタリングしたいわけですが、どうやるかというのが今回のテーマです。
やっかいなことにfluentdはsupervisorとworkerの2プロセスあってモニタリングしたいのはworkerです。まずはworkerのpidを求めないといけないわけですが、その辺の話は省略します。
process_nameがあるなんて知らなかったぜ。。。
http://www.fluentd.org/blog/fluentd-v0.12.18-has-been-released
以前、僕はworkerのpidに対してpsコマンドを実行して%cpuをモニタリングしてました。
が、しかしpsの%cpuは起動時からの平均CPU使用率なのでtopと比べると低くなりがちで、モニタリングするべきメトリクスではないです。
pidstatを使う手もありますが、こちらもインターバル指定しないとその瞬間の値を取れないです。
なので以下のようにして実行した値をモニタリングするのが正しいわけですが、これをそのままprometheusのexporterで実装するとポーリングのたびに5秒ブロックすることになるのでイマイチ
pidstat -h -u -r -p <PID> 5 1
というかprometheusはクエリが書けるので変に端末側で計算するのではなくCPU時間をそのままメトリクスとして取得してクエリを書いてGrafanaでグラフ化すればいい。
そんなノリで書いたfluentd_exporterがこちら
https://github.com/wyukawa/fluentd_exporter
最初のほうはworkerのpidを求めるためのアヤシイ処理が入っていますが、そこは置いといて最終的には/proc/(worker pid)/stat内のutime+stimeをメトリクスfluentd_cpu_timeとして取得しています。
このメトリクスに対して下記のようにクエリを書けば1sあたりどれだけCPUを使っているかがわかるので結果的にfluentdのCPU使用率になるはず。他の手法で取った値と比べて合ってる感じなので多分大丈夫
rate(fluentd_cpu_time[1m])