Edited at

fluentdで特定のパターンにマッチする行だけをwarnログを出さずに取得する

More than 1 year has passed since last update.

fluentdのin_tailプラグインを使ってログファイルから特定のパターンにマッチする行だけ取得し、かつwarnログ([warn]: pattern not match: "xxxxx")を出力させない方法について学んだので紹介。


検証環境


  • MacOS 10.12.6

  • fluentd 0.12.40


前提条件


  • ログはJSONやLTSVなどの構造化されたフォーマットで出力されていない


  • in_tailformatオプションで正規表現を与えて取得する必要がある

  • ログは様々なフォーマットで出力される可能性がある。例えば、スタックトレースのログが含まれる場合がある。

このようなログファイルを相手に、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ログが出力されなくなり、パターンにマッチする行は期待通りに取得できる。めでたしめでたし。