Fluentd Config DSL と fluent-plugin-forest
久しぶりにいつか書こう、書こうと思って放置してたやつ。 DSLの書き方もすぐ忘れるので、メモ代わりにしつつ…
会社のログ管理としてFluentd: Open Source Log Managementを利用しています。
Fluentdはプラグインを追加したり、作成したりして自分の好きなようにログや、アプリからのデータ等を加工できます。
しかし、いろいろできてしまう為設定ファイルがとても長くなってしまうことも…
しかし最近ではFluentdもDSLに対応し、Rubyのコードで設定ファイルが書けるようになりました。
Fluentd界隈ではバイブルのtagomorisさんのブログより
以下に適当なサンプルを用意しました、本気をだすとどんどん長くなります。 *1
# fluentd.conf <source> type forward </source> <match *.nginx> type file path /var/log/fluentd/nginx-* time_slice_format %Y%m%d-%H time_format %Y%m%dT%H%M%S%z compress gzip </match> <match *.app> type file path /var/log/fluentd/app-* time_slice_format %Y%m%d-%H time_format %Y%m%dT%H%M%S%z compress gzip </match> <match *.syslog> type file path /var/log/fluentd/syslog-* time_slice_format %Y%m%d-%H time_format %Y%m%dT%H%M%S%z compress gzip </match>
これをFluentd Config DSLで書くとこんな感じ
# fluentd.rb source { type :forward } ['nginx','app','syslog'].each do|tag| match("*.#{tag}") { type :file path "/var/log/fluentd/#{tag}-*" time_slice_format '%Y%m%d-%H' time_format '%Y%m%dT%H%M%S%z' compress 'gzip' } end
そこそこ減ったんじゃないでしょうか?
次のように実行してやると「$ fluentd -c fluentd.rb --log /tmp/fluentd.log
」実行でき、
/tmp/fluentd.log の中に fluentd.rbが展開されfluentd.confと同じ内容が出力されてるのが確認できます。
Config DSLで書いていて、思った通りの設定になってるか確認したいときは実行してログなど見ると良いかも、
テストだけなら次を実行すると「$ fluentd -c fluentd.rb --dry-run
」Fluentdは起動しないで、展開された設定が標準出力されます。
と、DSLの話をしてきましたがタイトルにはもうひとつ fluent-plugin-forest とあります。 このFluentdプラグインまたしてもtagomorisさんのブログを引用します。
私もいろんな場所で利用させて頂いています。
しかしDSLでこのプラグインを利用すると…
実行した設定ファイルはこれ
# fluentd.rb source { type :forward } match("**") { type :forest subtype :file template { time_slice_format '%Y%m%d-%H' time_format '%Y%m%dT%H%M%S%z' compress 'gzip' } ['nginx','app','syslog'].each do|tag| cases("*.#{tag}.*") { path "/var/log/fluentd/${tag_parts[1]}/${tag}-*" } end }
これを実行してみると
$ fluentd -c fluentd.rb --dry-run 2013-12-10 02:45:06 +0900 [info]: reading config file path="fluentd.rb" /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/config_dsl.rb:28:in `instance_eval': ./fluentd.rb:16: syntax error, unexpected '{', expecting keyword_when (SyntaxError) ./fluentd.rb:19: syntax error, unexpected '}', expecting keyword_end from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/config_dsl.rb:28:in `eval' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/config_dsl.rb:14:in `parse' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/engine.rb:72:in `parse_config' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/supervisor.rb:285:in `run_configure' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/supervisor.rb:108:in `dry_run' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/supervisor.rb:83:in `start' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/lib/fluent/command/fluentd.rb:146:in `<top (required)>' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:53:in `require' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:53:in `require' from /home/momin/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluentd-0.10.41/bin/fluentd:6:in `<top (required)>' from /home/momin/.rbenv/versions/2.0.0-p353/bin/fluentd:23:in `load' from /home/momin/.rbenv/versions/2.0.0-p353/bin/fluentd:23:in `<main>'
なんでかなーと思って、ちょこちょこ設定ファイル変更したりしてみても動かない…
よくよく考えてみると、fluent-plugin-forestの中には case が…はい、 つまり Fluentdの設定ではなくてRubyのコードして読み取られてたわけなんですよ… なのでちょこっとプラグインと設定ファイルを修正します
$ cd ~/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/fluent-plugin-forest-0.2.2/lib/fluent/plugin $ diff out_forest.rb out_forest.rb.bk 44c44 < when 'cases' --- > when 'case' $ cd - $ diff fluentd.rb fluentd.rb.bk 16c16 < cases("*.#{tag}.*") { --- > case("*.#{tag}.*") {
特に何も考えないでcaseの後ろにsをつけてみました…
そして再度実行…
$ fluentd -c fluentd.rb --dry-run 2013-12-10 02:56:51 +0900 [info]: reading config file path="fluentd.rb" 2013-12-10 02:56:51 +0900 [info]: gem 'fluent-plugin-forest' version '0.2.2' 2013-12-10 02:56:51 +0900 [info]: gem 'fluentd' version '0.10.41' 2013-12-10 02:56:51 +0900 [info]: using configuration file: <ROOT> <source> type forward </source> <match **> type forest subtype file <template> time_slice_format %Y%m%d-%H time_format %Y%m%dT%H%M%S%z compress gzip </template> <cases *.nginx.*> path /var/log/fluentd/${tag_parts[1]}/${tag}-* </cases> <cases *.app.*> path /var/log/fluentd/${tag_parts[1]}/${tag}-* </cases> <cases *.syslog.*> path /var/log/fluentd/${tag_parts[1]}/${tag}-* </cases> </match> </ROOT> 2013-12-10 02:56:51 +0900 [info]: adding source type="forward" 2013-12-10 02:56:51 +0900 [info]: adding match pattern="**" type="forest"
するとちゃんと動作してくれました。
実際会社ではDSL使ってないのでこんな修正はいらないのですが、 もしDSL使ってfluent-plugin-forest利用される場合は考慮いただけたらなと思います。
*1:ファイルを分けてincludeする手もありますけど…