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

たごもりすメモ

コードとかその他の話とか。

Fluentdでparser用の正規表現を書く・試す

fluent

こんなエントリを目にしたので、なんか書こうかなと思った。

fluentdのformat(正規表現)の作り方について試行錯誤中 #fluentd - Glide Note - グライドノート

Fluentd の in_tail や拙作 fluent-plugin-parser ではログのparse用の正規表現を指定することになるが、確かにこれを設定してログを流して試して直して、というのはいささか効率が悪い。ので、簡単に試す方法を書いてみる。

なお irb を使う手順。ruby 1.9系がインストールされていればたぶん入っているけれど td-agent だとちょっとどうだっけ。適当にがんばっていただきたい。

とりあえず以下のようなログをparseしたいとする。

Jul 16 00:45:47 BJA login[58879]: USER_PROCESS: 58879 ttys002

irbを起動するが、td-agent の場合はまずLOAD_PATHにfluentdのライブラリを加える必要がある。rvm(やrubiesなど)で gem install fluentd している場合は最初の LOAD_PATH の手当ては不要。

事前にlibのパスを確認する必要がある。 /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.XX/lib あたりにあるはず。

$ irb
:001 > $LOAD_PATH.push /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.xx/lib

そしたら以下のようにして確認する。

require 'fluent/config'
require 'fluent/parser'
require 'fluent/engine'

log = 'Jul 16 00:45:47 BJA login[58879]: USER_PROCESS: 58879 ttys002'

regexp = /^(?<date>\w{3} \d\d (\d{2}:){2}\d{2}) (?<host>\w+) (?<role>\w+)\[(?<pid>\d+)\]: (?<event>\w+): (?<info>\d+) (?<tty>.+)$/

parser = Fluent::TextParser::RegexpParser.new(regexp)

parser.call(log)
# => [1342367563, {"date"=>"Jul 16 00:45:47", "host"=>"BJA", "role"=>"login", "pid"=>"58879",
#  "event"=>"USER_PROCESS", "info"=>"58879", "ttyname"=>"ttys002"}] 

うまくいかなければ regexp を直して parser にセットしなおして parser.call(log) しなおす、というのを繰り返せばいい。

なお in_tail などの日時parseも試したければ以下のようにする。日時としてparseするフィールドを 'time' にしておくのがポイント。

require 'fluent/config'
require 'fluent/parser'
require 'fluent/engine'

require 'time'

log = 'Jul 16 00:45:47 BJA login[58879]: USER_PROCESS: 58879 ttys002'

regexp = /^(?<time>\w{3} \d\d (\d{2}:){2}\d{2}) (?<host>\w+) (?<role>\w+)\[(?<pid>\d+)\]: (?<event>\w+): (?<info>\d+) (?<tty>.+)$/

parser = Fluent::TextParser::RegexpParser.new(regexp)

parser.time_format = '%b %d %T'

parser.call(log)
# => [1342367147, {"host"=>"BJA", "role"=>"login", "pid"=>"58879", "event"=>"USER_PROCESS", "info"=>"58879", "ttyname"=>"ttys002"}] 

Time.at(1342367147)
# => '2012-07-16 00:45:47 +0900'

まあこんな感じじゃないすかね。