fluentdのmessageにtimeフィールドを残す #fluentd

fluentdのin_tailでパースされたメッセージは time,tag,message に分割されて次のプラグインまで流れますが、その際にmessageにtimeフィールドが残りません。これを残す方法はないか調べてみました。

現状

このような設定で動いているfluentdがあったとして

<source>
  type tail
  path /var/log/httpd/access_log
  tag apache.access
  format apache
</source>

<match apache.**>
  type stdout
</match>

ローカルホスト向けにcurlを打って

$ curl localhost

このようにaccess_logに残った場合

::1 - - [23/Nov/2013:10:23:59 +0900] "GET / HTTP/1.1" 403 5039 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"

fluentd内を流れるメッセージは以下のようになります。

(ここからtime)2013-11-23 10:23:59 +0900 (ここからtag)apache.access: (ここからmessage){"host":"::1","user":"-","method":"GET","path":"/","code":"403","size":"5039","referer":"-","agent":"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"}

messageからtimeが消えていますね。

解決策

fluent-plugin-record-reformerを使うことで解決しました。

sonots/fluent-plugin-record-reformer · GitHub

このpluginは流れてきたtime,tag,messageを加工することができるプラグインです。

インストールして

$ gem install fluent-plugin-record-reformer

設定ファイルを書き換えてfluentdを再起動します。

<source>
  type tail
  path /var/log/httpd/access_log
  tag apache.access
  format apache
</source>

<match apache.**>
  type record_reformer
  output_tag reformed.${tag}
  time ${time}
</match>

<match reformed.**>
  type stdout
</match>

ローカルホスト向けにcurlを打って

$ curl localhost

このようにaccess_logに残った場合

::1 - - [23/Nov/2013:10:23:59 +0900] "GET / HTTP/1.1" 403 5039 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"

messageの末尾にtimeフィールドがついています。

(ここからtime)2013-11-23 10:23:59 +0900 (ここからtag)reformed.apache.access: (ここからmessage){"host":"::1","user":"-","method":"GET","path":"/","code":"403","size":"5039","referer":"-","agent":"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2","time":"2013-11-23 10:23:59 +0900"}