fluentdのin_tail
プラグインを使ってログファイルから特定のパターンにマッチする行だけ取得し、かつwarnログ([warn]: pattern not match: "xxxxx"
)を出力させない方法について学んだので紹介。
検証環境
- MacOS 10.12.6
- fluentd 0.12.40
前提条件
- ログはJSONやLTSVなどの構造化されたフォーマットで出力されていない
-
in_tail
のformat
オプションで正規表現を与えて取得する必要がある - ログは様々なフォーマットで出力される可能性がある。例えば、スタックトレースのログが含まれる場合がある。
このようなログファイルを相手に、fluentdのwarnログを出さずに特定のパターンにマッチする行だけを取得していく。
雑にやるとwarnログが出る
まず、以下のように単純に取得したい行のパターンをformat
に与えるとどうなるか。
<source>
@type tail
tag sample.log
path /Users/foo/work/fluentd/sample.log
format /\[(?<level>[A-Z]+)\]\s+status_code=(?<status_code>[0-9]+)\s+message=(?<message>.+)/
</source>
<match sample.log>
@type file
path /Users/foo/work/fluentd/output.log
</match>
パターンにマッチするログを与えた場合は当然問題ない。
$ echo '[INFO] status_code=200 message=hello world' >> /Users/foo/work/fluentd/sample.log
しかし、パターンにマッチしない行を与えた場合は...
$ echo 'hello world' >> /Users/foo/work/fluentd/sample.log
以下のようなwarnログがfluentdのログに出力されてしまう
2017-08-25 23:43:08 +0900 [warn]: pattern not match: "hello world"
どうするか?
format
オプションに全ての行にマッチするパターンをor条件で与えた後、いずれかのキーが空の行をfilter_grep
で弾くことで実現できる。
<source>
@type tail
tag sample.log
path /Users/hiroki/work/fluentd/sample.log
# OR条件として「.*」を与えてすべての行をマッチさせる
format /\[(?<level>[A-Z]+)\]\s+status_code=(?<status_code>[0-9]+)\s+message=(?<message>.+)|.*/
</source>
# status_codeが空の行を弾く
<filter sample.log>
@type grep
exclude1 status_code ^$
</filter>
<match sample.log>
@type file
path /Users/hiroki/work/fluentd/output.log
</match>
このように設定するとパターンにマッチしない行でもwarnログが出力されなくなり、パターンにマッチする行は期待通りに取得できる。めでたしめでたし。