Fluentd 如何分离 Docker 容器的 stdout 与 stderr 日志?

Docker fluentd 驱动提供 source 字段,json-file 使用 stream,CRI 格式则不同。本文用 rewrite_tag_filter 按 source 改写 tag,分别识别 stdout、stderr 和未知来源,再按需配置输出。本文给出完整配置。

最佳实践
Fluentd 如何分离 Docker 容器的 stdout 与 stderr 日志?封面

先区分输入格式:Docker fluentd 日志驱动提供 source 字段,json-file 使用 stream,Kubernetes CRI 又有不同格式。下面以 fluentd 驱动的 source 改写 tag,再按 stdout/stderr 分流。

配置示例

<source>
  @type forward
  bind 0.0.0.0
  port 24224
</source>

<filter docker.**>
  @type record_transformer
  enable_ruby true
  <record>
    source ${record["source"].to_s.empty? ? "unknown" : record["source"]}
  </record>
</filter>

<match docker.**>
  @type rewrite_tag_filter
  <rule>
    key source
    pattern ^stdout$
    tag stdout.${tag}
  </rule>
  <rule>
    key source
    pattern ^stderr$
    tag stderr.${tag}
  </rule>
  <rule>
    key source
    pattern /^(stdout|stderr)$/
    invert true
    tag unknown.${tag}
  </rule>
</match>

<match stdout.** stderr.** unknown.**>
  @type stdout
</match>

Docker 容器需配置 fluentd 日志驱动、可从 daemon 所在网络访问的接收地址,以及 docker.* 标签。安装并确认 fluent-plugin-rewrite-tag-filter 可用;来源为空或未知的事件应通过实际插件版本的缺失字段行为测试,上例先补 unknown 默认值以免被丢弃。TTY 模式可能合并 stdout/stderr,驱动缓冲、断连和丢失行为也需验证。不要把 Docker 内部日志文件当成通用稳定采集接口。

典型玩法

  • stderr 单独建来源索引;stderr 不等于 ERROR,仍需解析应用日志级别;
  • stdout 全量存档,stderr 额外发通知;
  • 只采 stderr,丢弃 stdout 降噪(流量大的服务)。

常见问题(FAQ)

Q:K8s 环境的容器日志路径? 常见路径为 /var/log/containers/,通常是软链;需按实际运行时的 CRI 或其他格式解析,不能直接用 JSON parser。可配合元数据插件关联 Pod。

Q:rewrite_tag_filter 要装插件吗? 是插件(fluent-plugin-rewrite-tag-filter),是否预装取决于发行包和镜像,应检查并显式安装,不能假定所有官方镜像内置。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台