この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、臼田です。
fluentdの設定は自由度が高くて、逆にどうやるのが最適なのかなーと悩むことがよくあります。
今回は「apacheのログを出力したい」のような単体のログではなくて、「OSに保存されているいろんなログを(比較的)楽にS3に出力したい」という需要に答える設定を考えてみました。用途としてはとりあえずローカルの出力されているいろんなアプリログを拾ったりですとか、あとはコンプライアンス用件で細かい様々なログを全てS3に保管したいといったところが上げられると思います。
fluentdの設定値の役割についてもある程度解説しつつ、設定を紹介したいと思います。
なお、インストール方法などは省略します。公式ドキュメントなどをご参照ください。
いろんなログをまとめてS3に出力する設定
まず/etc/td-agent/td-agent.conf
の設定を共有します。
# read apache logs
<source>
@type tail
<parse>
@type none
</parse>
path /var/log/httpd/access_log
pos_file /var/log/td-agent/tmp/access.log.pos
tag os.apache.access
</source>
# read secure logs
<source>
@type tail
<parse>
@type none
</parse>
path /var/log/secure
pos_file /var/log/td-agent/tmp/secure.pos
tag os.secure
</source>
# send to S3
<match os.**>
@type s3
s3_bucket yourbucketname
path ${tag}/
s3_region ap-northeast-1
time_slice_format %Y/%m/%d
s3_object_key_format %{path}%{time_slice}/%{index}.%{file_extension}
<format>
@type single_value
</format>
<buffer tag,time>
@type file
path /var/log/td-agent/s3/${tag}
timekey 30
timekey_wait 30
timekey_use_utc true
</buffer>
</match>
いくつか設定の説明をします。
全体
複数のsource
を指定して、1つのmatch
でS3に出力する構成です。
match
のtagをos.**
とすることによってos.
から始まるスキーマのタグを全て拾うようにしています。**
を指定すると全てのタグを拾う設定になるので一見そちらでいいように感じられますが、実際にはfluentdが内部的に利用しているfluentd.**
というスキーマのタグも拾われてしまうため、os.
というスキーマを使うようにしてみました。
ワイルドカードの書き方について補足すると、*
だと.
で区切られた単体の領域のみのワイルドカードのため、複数の.
で区切られたタグも一意に拾う場合には**
で指定する形になります。ワイルドカードについての公式ドキュメントはこちら。
sourceディレクティブ
sourceディレクティブはログが出力されるファイルパスを指定することになるので、取り込むログに対して1個1個指定する事を想定しています。サンプルでは2つだけですが、10個取り込みたいログファイルがあれば10個指定してください。
sourceディレクティブの中のparseディレクティブでnone
タイプを利用しているところが今回工夫している部分です。
例えば通常apacheのアクセスログを取り込む場合にはapache2
タイプを利用したり、apacheのエラーログであればapache_error
タイプを選択します。しかしながら、全てのログに対してparseのフォーマットを適用しようとすると、標準に含まれていないparseのプラグインを導入したり、自分で書いたりしないといけないです。
そこまで深く考えずに、とりあえずログをそのままの形式で転送したい場合に利用するのがnone
タイプです。これを利用すると、特にログをパースしないで1つのメッセージとして扱われます。公式ドキュメントはこちら。
あとは、tagをos.hoge.fuga
としてあげればOKです。ここで指定するtagがS3に出力する際のprefixに利用されるため、わかりやすい名前付けや階層分けを推奨します。.
で分割する階層も任意の数で問題ありません。
matchディレクティブ
上述していますがos.**
にて全てのsourceをまとめて1つのmatchで扱うように設定しています。
pathに${tag}
を指定することによってログ種別毎にprefixが切られます。その配下はtime_slice
等で分けていますが、このあたりは任意です。
sourceでnone
タイプを利用している場合には、出力側ではフォーマットにsingle_value
タイプを利用することが推奨されています。これは対になる役割となっており、メッセージをそのまま出力します。公式ドキュメントはこちら。
また、複数のsourceをワイルドカードで扱う場合にはbufferを分けて保存する必要があるため、bufferセクションのpathでも${tag}
を含めたり、tagとtimeを利用しているためbufferセクションのチャンクキーにてtag,time
を指定する必要があります。詳細はこちら。
おまけ
今回は実施していませんが、例えばAuto Scalingなどで複数のEC2インスタンスからログを出力する際にはprefix等でインスタンスIDを入れたくなります。その場合にはfluent-plugin-ec2-metadataを利用しましょう。
まとめ
fluentdでいろんなログをまとめてS3に出力する設定とその解説をしました。
それぞれの設定値についていろいろ公式ドキュメントを調べる必要があり苦労したので、少しでもわかりやすいようにと思ってまとめました。
ぜひご活用ください。