Fluentd meetup in Japanに参加してきたのでplugin書いてみた

“the missing log collector”ということで昨今話題の fluentd ですが、日本での使用事例も増えてきたこともあり大規模なセミナーが開かれたので参加してきました。

内容はとても充実していて、作者の古橋さんによる fluentd の概要から始まり、plugin の書き方、実例と続いていて 1 日で fluentd に詳しくなれるすばらしいイベントだったと思います。古橋さんのセッションで今までよくわかってなかった buffer plugin もイメージが持てましたし、@repeatedly さんのプラグイン作りの指南書のおかげで何を作れば自分のやりたいことができるのかが分かってきました。cookpad と NHN*2 の実例は非常に聴き応えのある内容だったので、もう一度資料見返しておこうと思います。

懇親会で fujiwara さんにカヤックでの利用も聞いたり、doryokujin さんや古橋さんに色々と fluent や TD の話も聞けたし、fluent の生死監視はどうするのがいいだろうとかも盛り上がってすごい有益でした。

fluent-aggregate-filter plugin 書いてみた

さて、前々から fluentd をサーバの統計情報収集ツールとして使いたいと思っていました。どういうものかというと、例えばvmstat 1の結果を fluentd に投げ続けると、1 分毎に集計して最大最小や平均、95 パーセンタイルなどにして 1 分間を代表する 1 レコードとして投げてくれるというもの。

今回セッションを聞いて Fluent::TimeSlicedOutput を継承して、output せずにもう一度 emit する plugin を書けば output は自由な plugin 使えるので良さそうと思い立って、1 日費やして初めての ruby をやってました。

まず、テスト駆動で書きたかったので tagomoris さんの下記エントリを参考にして自分の llenv の環境下に作業環境を準備。

色々やってたらなんとかllenv exec rake -- testが通る様になったので無事書き始めました。ruby は慣れてくると書きやすいなぁという印象ですが、慣れるまで苦労しました。。。

というわけで、とりあえずそれっぽく動くかもしれないものはできました。

使い方としては以下の様な config になります。

<match debug.**>
  type aggregate_filter
  add_prefix aggregated  # optional(default aggregated)
  percentile 95          # optional(default 95)
</match>
<match aggregated.**>
  type stdout
</match>

こうすることで、

$  echo '{"aaa":1, "bbb":2}' | llenv exec fluent-cat debug.test
$  echo '{"aaa":3, "bbb":1}' | llenv exec fluent-cat debug.test
$  echo '{"aaa":5, "bbb":9}' | llenv exec fluent-cat debug.test
$  echo '{"aaa":1, "bbb":9}' | llenv exec fluent-cat debug.test

2012-02-05 22:25:00 +0900 aggregated.debug.test: {"aaa":{"num":4,"min":1,"max":5,"pct95":3,"sum":10.0,"avg":2.5,"var":2.75},"bbb":{"num":4,"min":1,"max":9,"pct95":9,"sum":21.0,"avg":5.25,"var":14.1875}}

みたいな感じで 1 分間のレコードをそれっぽく集計しています。初めての ruby でも大体 6 時間くらいあればこのくらいまで作れる fluentd はすばらしいですね。この plugin はもうちょっとブラッシュアップしていこうと思います。