docker fluentd logging driver の基礎的な設定

More than 1 year has passed since last update.

https://docs.docker.com/engine/admin/logging/fluentd/

docker container では、コンテナ内の何かしらのプログラムが標準出力 (strout) や標準エラー (stderr) に出力した内容を docker logs コマンドで取得することができます。

しかし能動的に取得しいにいくだけでなく、何かしら別の方法で forward をしてくれると助かることもあります。

docker では logging driver という機構で、stdout / stderr に出力された内容を指定された方法で forward する仕組みがあります。

サポートされている logging driver の種類については以下公式ドキュメントを参照ください。

https://docs.docker.com/engine/admin/logging/overview/#supported-logging-drivers


fluentd logging driver

そのうち、この記事では fluentd logging driver についてのみ触れます。


overview

https://docs.docker.com/engine/admin/logging/fluentd/

fluentd logging driver は、上述の logging driver の forward 先として、fluentd の in_forward を送信先に指定することができる logging driver です。


configuration

以下、最もシンプルな例を docker compose の設定記述を例に記します。

        logging:

driver: "fluentd"
options:
fluentd-address: "localhost:24224"
tag: "docker.logging_driver.masashi.sada"

上記の例では、標準出力の内容を localhost:24224 で起動されている td-agent / fluentd の in_forward port に対して docker.logging_driver.masashi.sada というタグで書き込みを行います。


log sample

こちらは docker container 上で puma を起動した際の例です。

20170411T060729+0000    docker.logging_driver.masashi.sada        {"source":"stdout","log":"Puma starting in single mode...","container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a","container_name":"/masashi_dev_puma"}

20170411T060729+0000 docker.logging_driver.masashi.sada {"container_name":"/masashi_dev_puma","source":"stdout","log":"* Version 3.8.0 (ruby 2.3.3-p222), codename: Sassy Salamander","container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a"}
20170411T060729+0000 docker.logging_driver.masashi.sada {"container_name":"/masashi_dev_puma","source":"stdout","log":"* Min threads: 5, max threads: 5","container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a"}
20170411T060729+0000 docker.logging_driver.masashi.sada {"container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a","container_name":"/masashi_dev_puma","source":"stdout","log":"* Environment: development"}
20170411T060730+0000 docker.logging_driver.masashi.sada {"log":"* Listening on tcp://0.0.0.0:3000","container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a","container_name":"/masshi_dev_puma","source":"stdout"}
20170411T060730+0000 docker.logging_driver.masashi.sada {"source":"stdout","log":"Use Ctrl-C to stop","container_id":"a1e6529928d6b06510b2a0ea0bb8813f0e4a5ecf240a2e544da1e9617310f41a","container_name":"/masshi_dev_puma"}

name
description

source
stdout or stderr

container_id
docker container の id

container_name
docker container の名前

log
出力内容


more detail

上記のような設定でも動作はしますが、こちらの設定の場合、docker container 起動時に fluentd / td-agent が起動していないなどの理由で該当 port が listen しない場合、 docker container が起動に失敗します。

ERROR: for puma  Cannot start service puma: Failed to initialize logging driver: dial tcp 127.0.0.1:24224: getsockopt: connection refused

そこまでの強い依存関係を要求しないのであれば、以下のように fluentd-async-connect = true を設定すると、docker container の起動時に接続を確立的無くても contaienr は起動するようになります。

        logging:

driver: "fluentd"
options:
fluentd-address: "localhost:24224"
tag: "docker.logging_driver.masashi.sada"
fluentd-async-connect: "true"

fluentd-async-connect = true にした場合は docker container の fluentd logging driver にて buffering と再送処理が行われます。

無尽蔵に buffering したりリトライを行ったりすると container の安定性に不安が出てきますので、fluentd-async-connect = true に設定した場合は以下のパラメータについて最適にチューニングを行いましょう。


  • fluentd-buffer-limit


    • default = 8MB



  • fluentd-retry-wait


    • default = 1000ms



  • fluentd-max-retries


    • default = 1073741824




parse logs

私が知る限り、fluentd logging driver では出力内容に応じてタグを出し分けたり、log 自身の内容を JSON として情報を構造化する方法をサポートしていないように見えます。

標準の項目以外のログ情報を構造化したい場合は、後続の fluentd / td-agent にて少し工夫をして parse 処理をしてあげる必要があります。

以下の Qiita などが、方法としては参考になります。

DockerのFluentd logging driverを通したltsv形式アクセスログをパースする


tag

最終的にアグリゲートされていく事を想定して、転送されるログデータの中には何かしらの形で


  • container_id

  • container_name

のいずれかもしくは両方が含まれている方が扱いがしやすくなると思います。

これらは fluentd logging driver の出力する JSON にも含まれているため、タグとして表現するか、データ構造として表現するかは、アプリケーションによって扱いやすい方法を採用すると良いと思います。

タグで表現する場合は以下のような形で変数で記述できます。以下は docker-compose での例です。

                tag: "docker.logging_driver.masashi.sada.{{ImageName}}.{{.ID}}"

使用できる変数の詳細は以下ドキュメントを参照ください。

https://docs.docker.com/engine/admin/logging/log_tags/


conclusion

使い方は適材適所ですが、 container が出力する内容を適切に capture 出来るという意味で fluentd logging driver は便利なので、現場の要件にあわせて使用していきましょう。