nがひとつ多い。

えぬなおの技術的なことを書いていくとこ。

【Fluentd】fluentdでdockerのlogを直接読み込む時にfluent-plugin-dockerが使いやすい

dockerのログのデフォルトのフォーマットはjsonな事が多いね

ってか今もデフォルトでjsonだっけ?とりま今現状GKEとかEKSとかECSとかで、アプリがどっかに吐いたJSON形式のログをfluentdのdaemonsetでログを見に行って出力してみるとこんな感じになってる。

{"log":"{\"Level\":\"INFO\",\"Time\":\"2019-02-25T07:14:56.434+0900\",\"Caller\":\"logging/logging.go:57\",\"Msg\":\"HANDLER\",\"method\":\"GET\",\"path\":\"/rd\"}\n","stream":"stdout"}

ただjsonならまだどうにかしようがあるが、例えばこのケースだとバックスラッシュはあるし元々のログに改行があったりするので \n もあって。せっかくアプリのコードで中身をjsonで出している時がむしろキツいと言う悲しい時がある。とても厄介なことはjsonの値に \n のようなエスケープシーケンス系が入っていると、このデータはjsonとしても読み込まれなくなる。

どうするの

dockerの機能を使ったり、docker logのフォーマットを起動時に変更すればいいと思うが、そんないつでも変更できる状況にあれば苦労しない。
その場合このままでもfluentd限定だが、以下のgemで解決できたりする。

github.com

半日かけてググった結果、このfilterが一番スマートだった。

いぐざんぽー

とりまプラグインをいれないといけないので、起動まえにgemでいれておく。

$ gem install fluent-plugin-docker

$ fluent-gem install fluent-plugin-docker

コンフィグは↓こんな感じ

fluent-conf

<source>
  type tail
  path /var/log/containers/hoge-*.log
  pos_file /fluentd/log/hoge-containers.log.pos
  time_format %Y-%m-%dT%H:%M:%S.%NZ
  tag hoge
  format json
  read_from_head true
</source>

<filter **>
  type docker
</filter>

<match hoge>
...

filtertype dockersourcematch の間で挟むだけ・・・簡単すぎて気絶した・・・!

こうすると、

{"log":{"Level":"INFO","Time":"2019-02-26T00:00:11.143+0900","Caller":"logging/logging.go:57","Msg":"HANDLER","method":"GET","path":"/rd"},"stream":"stdout"}

はい解決(^p^)
これでデータとして使いやすくなった。