Fluentd でコンテナログを転送しているのだが、Kubernetes のバージョンを上げてコンテナランタイムがcontainerdに変わってからログが転送されなくなった。
調べたらdockerのときは /var/log/containers
にJSONで出力されていたログが、containerdでは [timestamp] stderr F [time] ...
のような1行形式に変わっていた。
Kubernetesのコンテナランタイムがcontainerd場合のFluent Bitでのログ転送について - ブログ - 株式会社Smallit(スモーリット)
https://github.com/fluent/fluentd-kubernetes-daemonset/issues/412
<system>
rpc_endpoint 127.0.0.1:24444
</system>
<source>
@type tail
path "/var/log/containers/my-container.log"
tag container-log
<parse>
@type /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
pos_file /fluentd/logs/my-container.log.pos
</source>
<match container-log>
@type stdout
<buffer>
flush_mode immediate
</buffer>
</match>
プレーンテキストになったことでもうひと工夫必要
複数行に渡ってログが出力されるとき、grepでは先頭の行しか拾えないので、もしJavaのスタックトレースなどで形式がマッチしない場合は工夫がいる。 自分のケースでは使わなかった。
multiline Parser を使うのがよさげ
<parse>
@type multiline
format_firstline /\d{4}-\d{1,2}-\d{1,2}/
format1 /^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/
</parse>