こんにちは @sonots です。
Haikanko OSS化への道、連載第一弾です。Haikanko は大分できあがった感があるんですが、OSS化するためには内部モジュールの gem 化やテスト、ドキュメントの整備作業していないとむりだなー、と感じているので、連載と称して少しずつやっていこうと思ってます。※ Haikanko についてはこちら => HaikankoというFluentdクラスタ管理ツールの話をしてきた(1) #fluentdcasual
ということで、その第一弾と称して、fluent-plugin-grepcounter という fluentd のプラグインを gem 化して rubygems に置いたので紹介します。
何するもの?
ログメッセージを grep のように正規表現で絞り込むと同時に、マッチしたメッセージの数をカウントしてくれるものです。カウントがある一定数を超えた場合のみ出力する、といった制御もできます。
やりたかったこと/できること
fluent-agent-lite を使ってアプリが出力しているログを fluentd に送り、5分の間に出力された "warn" という文字列にヒットするログメッセージが xx 件以上ならば、IRCおよびメールで通知、といったようなことがやりたかったので作りました。メールの本文にはヒットしたログメッセージ全件を貼付けたかったので、既存の fluent-plugin-datacounter + fluent-plugin-notifier ではそれはできないなー、と思って作成しました。
使い方
https://github.com/sonots/fluent-plugin-grepcounter の README にも書いていますが。
例えば、以下のようなメッセージが fluent-agent-lite から送られてくるとして
ヒットしたメッセージはデフォルトでは出力されないので、もし、出力したい場合は output_matched_message オプションを true にして、delimiter を指定してください。
(2013年05月05日 加筆) デフォルトでヒットしたメッセージも出力されるようになりました。
(2013年11月30日 加筆) delimiter オプションで delimiter を指定すると message が join されて配列ではなく文字列として出力されます。
syslog.host1: {"message":"2013/01/13T07:02:11.124202 INFO GET /ping" }
syslog.host1: {"message":"2013/01/13T07:02:13.232645 WARN POST /auth" }
syslog.host1: {"message":"2013/01/13T07:02:21.542145 WARN GET /favicon.ico" }
syslog.host1: {"message":"2013/01/13T07:02:43.632145 WARN POST /login" }
|
こんなかんじで設定すると
<match syslog.**>
type grepcounter
input_key message
regexp WARN
count_interval 60
exclude favicon.ico threshold 1
add_tag_prefix warn.count
</source>
|
message (input_key)フィールドの文字列のうち、WARN (regexp)という文字がヒットする数を60秒間(count_interval)カウントします。exclude で指定した文字は除外され、カウント数が threshold で指定した値を超えた場合だけ、出力されます。add_tag_prefix で出力メッセージのタグを改変できます。
出力はこんなかんじになります。count はもちろん出力されますが、自分の利便性のために、入力のタグ名と、その最後の要素も出力されるようになっています。ホスト名を取りたかったんですよね。
warn.count.syslog.host1: { "count":2, "input_tag":"syslog.host1", "input_tag_last":"host1" "message":["2013/01/13T07:02:13.232645 WARN POST /auth","2013/01/13T07:02:43.632145 WARN POST /login"], } |
<match syslog.**>
type grepcounter
count_interval 60
input_key message
regexp WARN
exclude favicon.ico
threshold 1
add_tag_prefix warn.count
delimiter \n
</source>
|
出力はこんなかんじになります。
warn.count.syslog.host1: {
"count":2, "input_tag":"syslog.host1", "input_tag_last":"host1", "message":"2013/01/13T07:02:13.232645 WARN POST /auth\n2013/01/13T07:02:43.632145 WARN POST /login" } |
Acknowledgements
fluent-plugin-grepcounter を作成するにあたって、例によって @tagomoris さんの https://github.com/tagomoris/fluent-plugin-datacounter を大分参考にさせていただきました。ありがとうございます。
また、今回テストは fluentd のプラグインにしては珍しく、rspec で書いています。rspec でテストを書くにあたって、@SpringMT さんの https://github.com/SpringMT/fluent-plugin-resque_stat を参考にさせていただきました。ありがとうございます。
おわりに
fluent-plugin-grepcounter は以前書いたこちらの記事 HaikankoというFluentdクラスタ管理ツールの話をしてきた(2) - Fluentd側の話 #fluentdcasual で fluent-plugin-watchcatcounter と呼んでいたやつですね。それを汎用的なプラグインとして整理して、それなりの名前を付け直してリリースしました。Haikanko でログのキーワード監視機能を実現するために使用しています。
こんな感じで、整理作業を進めていくのでよろしくお願いいたします。かしこ。