Docker 的 Fluentd 日志驱动如何处理多行日志?

Docker fluentd 日志驱动本身按行切割堆栈等多行日志,需配 fluentd 的 concat 过滤器按模式合并(如 Java 堆栈以空白开头并入上行)。本文给出 fluentd 侧 concat 配置与容器标签方案。

最佳实践
Docker 的 Fluentd 日志驱动如何处理多行日志?封面

fluentd 日志驱动只负责按行转发,多行合并在 Fluentd 侧用 concat 过滤器完成:定义"新行起始模式"(如日期开头),不符合的行并入上一条——Java 堆栈、多行 SQL 就能还原为一条日志。

Fluentd concat 配置

<filter docker.**>
  @type concat
  key log                                # 消息字段名
  multiline_start_regexp /^\d{4}-\d{2}-\d{2}/   # 新日志以日期开头
  separator "\n"                         # 保留多行边界
  use_first_timestamp true
  stream_identity_key source
  timeout_label @CONCAT_TIMEOUT
  flush_interval 5
</filter>

超时记录需要对应 label 输出,例如:

<label @CONCAT_TIMEOUT>
  <match **>
    @type stdout
  </match>
</label>

这处理应用多行,不等同于 Docker 因长度拆分的 partial records 重组,后者需按插件 partial 配置处理。

驱动侧配置

docker run --log-driver=fluentd \
  --log-opt fluentd-address=127.0.0.1:24224 \
  --log-opt tag="docker.{{.ID}}" \
  myapp

tag 里带容器 ID,concat 的 key 对应消息中的 log 字段,source 区分 stdout/stderr。fluentd-address 由 Docker 守护进程访问,不会自动使用应用容器的服务名解析;请替换为守护进程可达的地址。

注意事项

  • concat 不会自动按容器与输出流隔离;本例用唯一容器 tag 和 stream_identity_key source 防止混合;
  • flush_interval 是等待"后续行"的超时,太小会把正常多行切断;
  • 更稳的方案是应用直接输出单行 JSON(堆栈整体放字段里),天然无多行问题。

常见问题(FAQ)

Q:concat 后时间戳是哪行的? 仅在 use_first_timestamp true 时使用首条时间,本例已显式开启。

Q:能按"缩进行并入上行"吗? 可以:multiline_start_regexp /^\S/,非空白开头的才算新行。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台