読者です 読者をやめる 読者になる 読者になる

年中アイス

いろいろつらつら

fluent-plugin-parserから出る"pattern not match"メッセージを出さないようにしたい

fluentd

2013/02/27追記

@さんに無事pull requestマージしていただけました。ありがとうございます。
fluent-plugin-parserの0.2.2から使えるようになっています。

  • 設定名をsuppress_parse_error_logに変更
  • テスト例をいただいて、無事テストコードも追加

githubRubyになるとは。今度、pull request周りをまとめたい。。。
とりあえずgithubはこれ見ながらやりました。
WEB+DB press vol.69 isbn:4774151041
追記ここまで。


ちょっと必要だったので、ついでにpull request投げられないかと模索中。
そもそもの経緯としては、綺麗でないログ(デバッグに近いログ)から、特定のフォーマットにマッチする行だけfluentdに乗せて、集計とかgrowthforecastに流したいというところから。

こんな雰囲気のログです。いろいろ混ざってます。

...
[2013/2/20 11:11:11] APP hoge=hogehoge foo=foofoo #この行だけ対象にしたい
[2013/2/20 11:11:12] DB connection error
Stack trace...
...
[2013/2/20 11:11:30] ...
...
[2013/2/20 11:12:11] APP hoge=hogehoge foo=foofoo #この行だけ対象にしたい
...

今でもfluent-plugin-parserで出来てはいるんですが、td-agent.logに、pattern not match...といったメッセージがひたすら出続けて、容量を食っています。*1

2013-02-20 23:06:15 +0900: pattern not match: 一致しなかった文字列
2013-02-20 23:06:16 +0900: pattern not match: 一致しなかった文字列
2013-02-20 23:06:17 +0900: pattern not match: 一致しなかった文字列
...

正規表現が間違っていたときなどに、このメッセージで気づけるようになっているので、出ること自体はあるべき姿かなと思います。

ただ、今回のように実際の運用上、アプリケーション側に手を入れる権限・時間が無いなどで、やむを得ないケースがあります。本当は、ログの出力を変えるべきなんですが、それができない。

そんなときにさっと、1つオプションを指定して、わかりきったpattern not matchメッセージを抑制することができれば・・・!

ということで、変更をかけてみます。

変更内容

unmatch_silentというオプションを追加。bool型でデフォルトはfalse(今までと同じく、pattern not matchメッセージを出す)

fixed_parser.rb
# 11行目ぐらい
    config_param :unmatch_silent, :bool, :default => false

# 他、text,json,apacheで$log.warnしてるのをunless @unmatch_silentでくくる
unless @unmatch_silent
  $log.warn "pattern not match: #{text}"
end

単体テスト

ruby単体テストよくわかんないと思いつつ、parserのテストを見ながら書いてみたり、Twitterにつぶやいたら、@さんから、助言をいただきまして。ありがとうございます。

https://twitter.com/repeatedly/status/303885233755938819:twitter

でもまだうまく行かず。。。
プラグイン内では、$log.warnと書いてあるので、標準のロガーでどこか別のところに出てるのかな。。。この辺はRubyをもう少し知る必要があるのかな。
gistにテストコード抜粋
https://gist.github.com/reiki4040/5004644

動作テスト

とりあえず動くかを確認しようと、/etc/td-agent/plugin/の中に、out_parser, fixed_parserを入れます。
このときに、out_parserのparserをmy_parserに変更しておき、すでにインストールされているparserプラグインとかぶらないようにします。

class Fluent::ParserOutput < Fluent::Output
  Fluent::Plugin.register_output('my_parser', self)

td-agent.conf側では、以下のように新しいを追加して、試します。まずは、pattern not matchメッセージが出る状態。

<source>
  type tail
  path /var/log/td-agent/hoge.log
  pos_file /var/log/td-agent/hoge.log.pos
  tag exsample.silent
  format /(?<message>.*)/
</source>

<match exsample.silent>
  type my_parser
  tag exsample.silent.parse
  key_name message
  format /^hoge=(?<hoge>.*) foo=(?<foo>.*)$/
  #unmatch_silent true
</match>

<match exsample.silent.parse>
  type file
  path /var/log/td-agent/exsample.silent.parse.log
</match>

td-agent再起動(or起動)

sudo /etc/init.d/td-agent restart

これで、以下のようにhoge.logに新しい行を追加

echo 'abcedfg' >> /var/log/td-agent/hoge.log

td-agent.log

2013-02-20 23:30:15 +0900: pattern not match: abcedfg

そして、今回の変更である部分を試す。td-agent.confの上で追加したコメントをはずす。

  unmatch_silent true

td-agent再起動

sudo /etc/init.d/td-agent restart

再び、echoで送っても、td-agent.logに、pattern not matchメッセージは出ない。修正は成功。
ちなみに、unmatch_silent falseで、メッセージが出ることも確認。

あとはこれをpull request

unmatch_silentというオプション名はよいのかどうかは検討すべき点として、機能自体は入れてもいいのかなーと思ってます。
そんなわけで@さんにpull request投げようと思ってますが、初めてなので手間取りつつ。

あとpull request時の英語が難点。。。単体テストもないけど。

今回やってみてわかったこと

  • /etc/td-agent/plugin/にout_*で入れるだけで使えるので、プラグイン開発するときに実行するのは簡単そうだったこと。
  • プラグイン単体テスト用にドライバがあるので、テストも書きやすそうなこと。
  • たいした内容じゃないのに、慣れてないせいで、すぐpull request飛ばせてないこと

とりあえずあとはpull requestがんばろう。

rubyだったり、fluentdだったり、何か間違っている部分等があれば指摘もらえるとうれしいです。

*1:td-agent.logがローテートしないのは、また別の問題(次のtd-agentリリースで修正される様子? https://github.com/treasure-data/td-agent/issues/9