update.Fluentdはデータを流すのに非常に便利なツールでそこら中で使われている(個人調べ)。そのため、なんかいろんなところで設定を見るのであるが、タグに情報が付いていたりフィールドに情報がついていたりして、あれ、これどうなってるんだっけ感に襲われることがよくある。このあたり自分でも混乱しがちなので、普段どのように考えているかだいたいまとまった気がしたところで書いておくことにした。Fluentdのデータ構造まずはFluentdのデータ構造を知っておいた方が良い。Fluentdの内部データはMessagePackで符号化されているが、Fluentdのデータ構造は単なるハッシュではなく、時刻(time)とタグ(tag)という属性を持っている。"value"}]レコードレコード(record)は入力されたデータそのものであり、tailプラグインであれば、tailした1行のデータに相当する。重要なことは、時刻、タグはレコードそのものに含まれている訳ではなく、あくまでも付与されている属性のようなものと言うことだ。実際の例を見てみよう。tailプラグインでapacheログを入力する場合、次のように記述する。stdout</match>このとき、access.logの1行はパースされてレコードの内容に含まれる。Fluentdのログを見ると時刻はレコードの内容と別に出力され、log.apacheというタグが付与されているはずだ。apache2の設定がApacheのアクセスログから時刻として扱うフィールドを指定しているためだ。時刻(time)timeはレコードに付与されている時刻で主にTimeSlicedOutputを使用しているプラグインが出力する際に使用する。timeの付け方はInputプラグインにより異なるが、レコードを生成した時刻だったり、tailプラグインのようにtimeとして入力するものを指定出来たりする。tailプラグインの場合、正規表現やJSON、LTSV、TSVまたはCSVの場合、time_key属性で指定出来る。created_at</source>タグ(tag)タグはFluentdにおいて主要な特徴の一つでデータのルーティングに使用する。それぞれのInputプラグインのスレッドは全てのレコードにタグをつけて出力する。Fluentdはmatchする<match>をさがし、対応するOutputプラグインのスレッドにレコードを渡す。<match>にはワイルドカードも使用できるため、これによって複雑なルーティングが可能になっている。送信元ホストでタグを付けておいて、1台の集約サーバに送信し、そこで複数の出力先に振り分けることも出来る。...</match>OutputFilterOutputプラグインのいくつかはレコードの内容を変換し、タグを書き換えてもう一度Fluentdに渡す動作を行うものがある。これらのOutputプラグインはOutputFilterプラグインと呼ばれていることがある。fluent-plugin-numeric-monitorなどはこのようなプラグインの1つだ。stdout</match>なお、Fluentdは近い将来、Filter機能をサポートする予定で、このFilter機能を用いればタグを変更せずにフィルター処理が可能になる。どんな感じで設定を書くか基本的には次の方針で設定を書くとそれほど悩まずに出来る。レコードに含める例えば、同じホスト名という情報であってもタグに付与した方がやりやすいか、レコードに含めた方がやりやすいかは違ってくる。ホスト毎にGrowthForecastの異なるグラフに出力する、ホスト毎にmongoDBの異なるコレクションに含める場合はタグにホスト名を付与しておく。逆にRDBやファイルにそのまま出力したい場合は、レコードに含めていると余計な設定をせずに済む。タグによる振り分けタグによる振り分け機能を持っているOutputプラグインは多い。fluent-plugin-growthforecastやfluent-plugin-mongoは標準でタグ毎に振り分ける機能を持っているので、別々のグラフやコレクションにできる。tag_mapped</match>fluent-plugin-growthforecastではtag_forパラメータを使用することで、タグによってセクションを振り分けたり、グラフ名のprefixに指定したりできる。上記設定では、monitor.**のレコードは、GrowthForecastでは別々のセクションに振り分けられて出力される。fluent-plugin-mongoではtag_mappedパラメータを指定することで、タグ毎に異なるコレクションに出力されるようになる。これらはそれぞれのプラグインがそのような機能を持っているから実現できている訳で、フィールドによって振り分けられる機能を持っていればいい話でもある。Fluentdはそもそもタグのマッチングによりデータをルーティングするため、このつくりは自然なことだと思う。タグでの振り分けに対応していない場合プラグインがタグによる振り分けに対応していない場合、fluent-plugin-forestが便利だ。fluent-plugin-forestはタグ毎にOutputプラグインのスレッドを自動的に生成してくれる。</template></match>fluent-plugin-forestでは、${tag}(または__TAG__)プレースホルダを使用することで、タグ毎に異なるスレッドを動的に生成する。これによって、タグ毎に設定を書かなくても、テンプレートを書くだけで動的に設定が生成される。タグの一部分だけを使いたい場合、${tag_parts[n]}(または__TAG_PARTS[n]__)プレースホルダを使用すれば良い。詳しい説明は下記ブログが詳しい。Studioタグとレコードの内容を変換するここまで、タグとレコードのフィールドの値どちらに情報を持たせるか書いたが、実際には、タグの情報とレコードの内容を相互に変換する必要が生じる。いうとtailなどのプラグインで入力した場合レコードにしか情報が含まれず、動的にタグを付ける方法がないからだ。このタグとレコード内容の相互変換を行うことが出来るプラグインが存在する。fluent-plugin-rewrite-tag-filterとfluent-plugin-record-reformerだ。レコードの内容によりタグを変更するfluent-plugin-rewrite-tag-filterは正規表現マッチにより、レコードの内容に応じてタグを変更することが出来る。アクセスログにおけるステータスコードに応じてログを振り分ける場合は次のように記述する。stdout</match>fluent-plugin-rewrite-tag-filterではrewriterule#{n}というパラメータで正規表現と変換後のタグを指定する。rewriterule#{n}パラメータは数字が被らないように連番にする必要がある。変換後のタグにプレースホルダを使用することも出来る。すべてのステータスコード毎にタグを振り分ける場合は次の設定で良い。log.apache.status_other</match>この場合、ステータスコードの数分タグが振り分けられるので、大量にグラフが出来ないように気をつける必要がある。タグの情報をレコードの内容に変換するタグの情報をレコードに含める等、レコードを書き換える操作を行うには、fluent-plugin-record-reformerが便利だ。タグの一番最後の部分をレコードに含める場合は次のようになる。stdout</match>fluent-plugin-record-reformerは他にも様々な書き換えに使えて便利だ。まとめFluentdは、タグと時刻によって複雑なルーティングを可能にしている。タグによる振り分けをサポートしているOutputプラグインは多いし、fluent-plugin-forestを用いればすべてのOutputプラグインをタグによる振り分けに対応させることが出来る。レコードの時刻は特別な理由がない限り、レコードのフィールドにするのではなく、レコードのtimeとして扱われるようにInputプラグインの設定に気をつけよう。fileプラグインの他、Elasticsearchに出力するfluent-plugin-elasticsearchもLogstashフォーマットの@timestampフィールドにtimeを使用する。正しいtimeが指定されていない場合、ログの発生時刻とKibanaで扱う時刻がずれてしまって面倒だ。逆にTimeSlicedOutputを利用するfileプラグインなどは、レコードが遅延して配送された場合、古いfileにも出力されたり、到着順にならなかったりすることに気をつけよう。タグと時刻の扱いは面倒なところではあるが、うまく使いこなすことでFluentdでできることがぐんと広がる。ここに書いたことは自分なりのやりかたなので、他にもいろいろなやり方があるだろう。タグの設定方法とかはノウハウ次第なので、いろんなノウハウがWeb上に公開されるとうれしい。ログ収集ミドルウェアFluentd徹底攻略もおすすめだ。逆引きプラグインなどまとまっていて非常に便利。Amazonでは品切れになっていることもあるので、是非お近くの書店で買おう(宣伝)。requestStockLike596はるかさん@harukasanよろしくおねがいします。upLoginユーザーは見つかりませんでした。