fluent-plugin-forestで新規ログのチェック

fluent-plugin-forestはタグを動的に扱うことができて、非常に便利なプラグインです。 マジで @tagomoris ++ です。

<match service.*>
  type forest
  subtype file
  remove_prefix service
  <template>
    time_slice_format %Y%m%d%H
    compress yes
    path /var/log/${tag}.*.log
  </template>
</match>

と書いておくと、service.hogeservice.fugaも一つの設定で

  • /var/log/hoge.2012112019.XXXXX.log
  • /var/log/fuga.2012112019.XXXXX.log

を吐き出してくれます。

便利なんですが次のようなニーズ

  • 新しいタグ(ログ)が追加されたことを知りたい
  • 新しいログが適切なログかどうか、なにがしかの判断とかをしたい

に対しては対応することができません。

本題

forestは、新しいタグが追加された時に、次のようなログを出力します。

2012-11-20 21:07:10 +0900: out_forest plants new output: file for tag 'test.b'

もちろん、system.log自体をfluentdでtailしてもいいのですが私は、fluent.infotype execを使っています。

fluentd.conf

<source>
  type forward
  port 11111
</source>

<match fluent.**>
  type exec
  command ./checkTag.pl
  keys message
  buffer_path ./fluent.log
  flush_interval 1s
</match>

<match test.**>
  type forest
  subtype file
  remove_prefix hoge
  <template>
    time_slice_format %Y%m%d%H
    path ./${tag}.${hostname}.*.log
  </template>
</match>

checkTag.pl

#!/usr/bin/env perl
use strict;
use warnings;

open my $output, ">>newtag.log" or die $@;

my $data = $ARGV[0];
open my $input, $data or die $@;

while(<$input>){
    chomp;
    if($_ =~ /^out_forest\splants\snew\soutput:/){
        my $tag = ($_ =~ /file\sfor\stag\s\'([^\']+)\'$/ and $1);
        print $output "[$tag] added\n";
    }
}

close $input;
close $output;

ちょっと正規表現がアレですが、これで新規に追加されたタグを取り出して、newtag.logというファイルに書き出ことができます。 単に書き出すだけじゃなくて、これをどこかにnotifyしたり、なんらかのvalidationを行ったりして捗っています。