首页 > 解决方案 > 如何使用 fluentd 转发多行 docker 日志?

问题描述

以下是我用于转发 docker 日志的配置fluent.conf,我想添加多行解析。

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

Fluentd 有一个多行解析器,但它只支持in_tail插件。我尝试使用in_tail插件添加多行解析器并且它有效,但我无法将它添加到 docker 日志中。

<parse>
    @type multiline
    format_firstline /\d{4}-\d{1,2}-\d{1,2}/
    format1 /^(?<logtime>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}.\d{1,9}) \[(?<thread>.*?)]\ (?<level>[^\s]+)(?<log>.*)/
  </parse>

如何使用 fluentd 上的forward插件为 docker 日志添加多行解析器?

标签: loggingfluentd

解决方案


实际上,我为解决此问题所做的是将接收到的数据(从<source>类型转发)写入文件(<match>类型为 file),然后读取文件(<source>类型为 tail),此时我可以使用多行解析器。来自原始源的元数据(例如主机名、环境名称等)必须存储在文件名中,然后使用标记部分提取。

例子:

Docker 守护进程使用以下选项运行:

--log-driver=fluentd --log-opt tag=ecs.{{.ImageName}}

Fluentd 配置如下:

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

<match ecs.**>
  @type forest
  subtype file
  <template>
    time_slice_format %Y-%m-%d
    path /var/log/td-agent/ecs/${tag}.*.log
    format single_value
    message_key log
    append true
  </template>
</match>

<source>
  type tail
  format multiline
  format_firstline /\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\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}([,.]\d{1,4})*\S*)\s+(?<level>\w+)\s+\[(?<thread>.*?)\s*\]\s+(?<message>.+)/
  path /var/log/td-agent/ecs/ecs.*.java.*.log
  multiline_flush_interval 2s
  pos_file /var/log/td-agent/ecs/java-1.pos
  tag java.log-1.*
  refresh_interval 5
</source>

<match java.**>
  type elasticsearch
  host es-host
  port 9200
  index_name java
  logstash_format true
  logstash_prefix java
</match>

顺便说一句,您还可以在传递给 fluentd 的标记中包含来自 Docker 标签的值,使用 Docker 守护程序选项如下:

--log-opt tag='ecs.{{.ContainerLabels.ENVIRONMENT}}.{{.ContainerLabels.LOG_TYPE}}.{{.ContainerLabels.ARTIFACT_ID}}.{{.ContainerLabels.ARTIFACT_VERSION}}.{{index .ContainerLabels \\\"spinnaker.servergroup\\\"}}'

在上面的示例中,我为传递给 fluentd 的标签添加了 4 个标签,然后可以将其提取到字段中并传递给 Elasticsearch。


推荐阅读