fluentd で nginx のログを扱おうとしたのですが、ちょっと詰まったのでメモ。
fluentd では、apache の Combined Log Format (詳しくは Apache HTTP サーバ バージョン 2.4 ログファイル 等をご参照ください) を簡単に source として利用することができます。Combined Log Format は以下のように定義されます:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined CustomLog log/access_log combined
これに対する fluentd の source の設定(最小限)は次のようになります:
nginx での注意点
nginx もデフォルトでは Combined Log Format を利用するため、上記 fluentd の設定の path 等を変更すれば、そのまま fluentd は稼働します。しかし nginx の設定ファイルである nginx.conf を見ると、アクセスログに関して次のようなコメントが記載されています:
http { ... #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; ...
このログの設定は、最初の状態ではコメントアウトされていますが、Apache の設定ファイルである httpd.conf における Combined Log Format と比較すると、最後に http_x_forwarded_for という変数が追加されています。つまり、このコメントアウトされているログの設定をコメントインしてしまうと、Combined Log Format から外れてしまいます。
実際に nginx.conf の設定で上のログ設定をコメントインして fluentd にアクセスしてみると、"pattern not match" と出力されます:
[01:55:47 root@bynatures ~]# td-agent -vv
...
2013-01-07 01:55:50 +0900: plugin/in_tail.rb:279:initialize: following tail of /var/log/nginx/access.log
(fluentd が起動したので、nginx のログが吐かれるようにブラウザでアクセス)
2013-01-07 01:55:55 +0900: fluent/parser.rb:38:call: pattern not match: 126.65.237.78 - - [07/Jan/2013:01:55:55 +0900] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11" "-"
これを修正するためには、nginx.conf で設定したログに合わせて fluentd の format 設定を修正する必要があります。以下の設定例では、http_x_forwarded_for に当たるログを forwarder として取得しています:
time_format の設定が増えていますが、これは format に自ら正規表現を指定したため、time として取得する日付のフォーマットを time_format の設定として与える必要があるためです。time_format の指定がないと、argument out of rangeのエラーが発生し、fluentd が正しく動作しません。(format に apache を指定した場合は、time_format も合わせて設定されますので明示的な指定は不要です。)