#fluentd で maillog を読み込んで MongoDB に投入

MTA が吐く maillog は普段あまり見ないのだけど、トラブルがあったときには大変重要。これも Mongo に入れれば、問い合わせがあったアドレスで検索してログを管理画面で見るとかできて便利!ということでやってみた。

# fluentd.conf
<source>
  type tail
  path /var/log/maillog
  tag maillog
  format /^(?<date>[^ ]+) (?<host>[^ ]+) (?<process>[^:]+): (?<message>((?<key>[^ :]+)[ :])? ?((to|from)=<(?<address>[^>]+)>)?.*)$/
</source>

正規表現がなかなかですが、これで maillog を parse して以下のような生ログから

2012-03-26T19:49:56+09:00 worker001 postfix/smtp[13747]: 31C5C1C000C: to=<foo@example.com>,
relay=mx.example.com[127.0.0.1]:25, delay=0.74, delays=0.06/0.01/0.25/0.42, dsn=2.0.0, status=sent (250 ok dirdel)

以下のように構造化されたログに変換した上で MongoDB に投入できます。

{
  "address" : "foo@example.com",
  "date"    : "2012-03-26T19:49:56+09:00",
  "host"    : "worker001",
  "key"     : "31C5C1C000C",
  "message" : "31C5C1C000C: to=<foo@example.com>, relay=mx.example.com[127.0.0.1]:25, delay=0.74, delays=0.06/0.01/0.25/0.42, dsn=2.0.0, status=sent (250 ok dirdel)",
  "process" : "postfix/smtp[13747]"
}

Postfix がログに吐く queue id ("31C5C1C000C") と、(to|from)= のようにメールアドレスが入った部分もマッチさせて別カラムに入れておくことで、

  • { address : "foo@example.com" } で検索して queue id を得る
  • その queue id で検索して一連の処理のログを抽出

ということが (indexを使って高速に) 可能になります。

複数台からの生ログには時系列で複数の処理が入り交じるので、一連のログのみ抽出するには多少工夫が必要ですね。