fluentd の parser と formatter をカスタマイズしていい感じにログを集約する

はじめまして、インフラエンジニアの末廣です。

この記事は TECHSCORE Advent Calendar 2014、15日目の記事です。

fluentd は今や広く使われているログコレクターであり、もはや説明の必要もないでしょう。
弊社でもログ集約・ログ解析の前処理・イベント検知などに利用しています。

この記事では fluentd (td-agent 2.1.2, fluentd-0.10.57) による生ログ集約を題材に、Parser plugin や Formatter plugin によるカスタマイズについて説明します。

※ 12月14日に v0.12 がリリースされて Parser plugin と Formatter plugin の新 API が利用できるようになったので、最後に新 API についても触れます。

生ログの転送

かつて、素の fluentd ではログを生のまま転送することはできませんでした。
当時は、fluent-agent-lite と file-alternative plugin を組み合わせたり、生ログをそのまま扱うプラグインを自作したりしていました。

v0.10.39 で in_tail などの format パラメータに none が追加されました。これにより、ログの行をそのまま "message" key の値として取り込むことができるようになりました。また、v0.10.50 で out_file などの出力 formatter に SingleValue が使えるようになり、特定の key に対応する値のみを出力できるようになりました。これらを組み合わせると、素の fluentd で生ログを転送することができます。

たとえば、 次のように in_tail と out_file を設定すると Apache の access_log を生ログのまま転送することができます。

複数ホストの生ログの集約

複数のホストからなるサービスでは、複数ホストのログを1つのファイルに集約したくなることがあります。このとき、ログの各行の先頭にホスト名を入れたくなるのですが、素の fluentd ではできません。そこで、v0.10.46 で導入された Parser plugin と v0.10.49 導入された Formatter  plugin を利用します。カスタムの Parser plugin で生ログとホスト名をレコードに挿入し、カスタムの Formatter plugin で生ログの先頭にホスト名を付与して出力します。

Parser Plugin

Parser plugin は TextParser クラスの内部クラスとして実装します。

下記の NoneWithHostnameParser は、生ログとホスト名(デフォルトは hostname -s で得られる値)をレコードに格納する Parser です。NoneParser をお手本にして、ホスト名をレコードに挿入するコードを追加しています。register_template で この Parser を none_with_hostname として登録しています。

/etc/td-agent/plugin/parser_none_with_hostname.rb

in_tail の設定で format に none_with_hostname を指定すると、生ログとホスト名がレコードに格納されます。

Formatter Plugin

Formatter plugin は TextFormatter モジュールの内部クラスとして実装します。

下記の HostnameAndMessageFormatter は、SingleValueFormatter とほぼ同じですが、出力行の先頭にホスト名を挿入する Formatter です。register_template で この Formatter を hostname_and_message として登録しています。

/etc/td-agent/plugin/formatter_hostname_and_message.rb

out_file の設定で format に hostname_and_message を指定するとログの各行の先頭にホスト名がつくようになります。

これらの plugin を組み合わせることにより、複数ホストの生ログをいい感じに集約しています。

おまけ:fluentd v0.12

ここまで書いたところで、12月14日に v0.12 がリリースされたことに気づきました。このリリースで Parser および Formatter plugin に新しい API が追加され、plugin をより簡潔に記述できるようになりました。v0.10.58 でも同様の記述ができるようになるようです。

新API の変更点は次の通りです。

  • ベースとなる Parser および Formatter クラスが定義されたので、これらを継承する形で plugin を実装する。
  • plugin の登録は、他の plugin と同様に  Plugin.register_parser および Plugin.register_formatter で行えるようになった。
  • Parser の実際の処理を実装するメソッドが call から parse に変更された。

新 API を利用すると上記の plugin はそれぞれ次のように記述できます。

/etc/td-agent/plugin/parser_none_with_hostname.rb

/etc/td-agent/plugin/formatter_hostname_and_message.rb

以前と比べると分かりやすくなりましたね。

参考

Comments are closed, but you can leave a trackback: Trackback URL.