用于多行的 Docker Fluentd 日志记录驱动程序

Posted

技术标签:

【中文标题】用于多行的 Docker Fluentd 日志记录驱动程序【英文标题】:Docker Fluentd Logging Driver For multiline 【发布时间】:2015-12-17 15:19:28 【问题描述】:

我正在尝试使用 fluentd 为 docker 环境创建一个集中式日志记录系统。目前,我可以使用 fluentd docker logging 驱动程序将 docker 日志发送到 fluentd,与使用 in_tail 方法读取 docker 日志文件相比,这是一种更简洁的解决方案。但是,我目前正面临多行日志问题。

从上图中可以看出,多行日志是乱序的,这对用户来说非常混乱。有什么办法可以解决这个问题吗?

谢谢。

连续

【问题讨论】:

在我做了一些进一步的研究之后,只是在这个主题上添加一些 cmets。乱序问题是由于 Fluentd 时间分辨率(现在没有亚秒级支持)。感谢这个答案link,我能够按顺序显示记录,至少用户在阅读此日志时不会感到困惑。 对于毫秒问题的另一种解决方案,请查看这篇博文work.haufegroup.io/log-aggregation/#timestamp-fix 您有解决方案了吗?我发现这个链接fluentd.org/guides/recipes/docker-logging about merge multiline log in docker before it send to fluentd,但实现对日志格式非常具体。 【参考方案1】:

我知道这不是流利问题的“答案”。但是本指南解决了 logstash 的问题: http://www.labouisse.com/how-to/2015/09/14/elk-and-docker-1-8

通过添加支持JSON

    json 
        source => "log_message"
        target => "json"
    

解析日志行后到他的过滤器

我从来没有找到 fluentd 的解决方案,所以改用这个解决方案

更新链接

【讨论】:

链接已失效。能详细解释一下吗?【参考方案2】:

使用 fluent-plugin-concat 插件帮助我解决了上述问题。

在fluent-conf中添加这些行

 <filter **>
  @type concat
  key log
  stream_identity_key container_id
  multiline_start_regexp /^\d4-\d2-\d2 \d2:\d2:\d2.\d3
  multiline_end_regexp /^\d4-\d2-\d2 \d2:\d2:\d2.\d3
</filter>

我的正则表达式正在检查日志中的 DateTimeStamp,其中每行以下面的日期和时间戳(注意"log":"2017-09-21 15:03:27.289)开头

2017-09-21T15:03:27Z    tag     "container_id":"11b0d89723b9c812be65233adbc51a71507bee04e494134258b7af13f089087f","container_name":"/bel_osc.1.bc1k2z6lke1d7djeq5s28xjyl","source":"stdout","log":"2017-09-21 15:03:27.289  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6"
2017-09-21T15:03:28Z    tag     "container_id":"11b0d89723b9c812be65233adbc51a71507bee04e494134258b7af13f089087f","container_name":"/bel_osc.1.bc1k2z6lke1d7djeq5s28xjyl","source":"stdout","log":"2017-09-21 15:03:28.191  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext"

另外,我必须在 Dockerfile 中添加以下行来安装插件

RUN ["gem", "install", "fluent-plugin-concat", "--version", "2.1.0"] 
#Works with Fluentd v0.14-debian

虽然这个正则表达式在异常发生的时候效果不好,但还是比以前好很多。 Fluentd Link, for reference.

【讨论】:

【参考方案3】:

看看他们文档中的multiline解析:http://docs.fluentd.org/articles/parser-plugin-overview#

您基本上必须指定一个匹配新日志消息开头的正则表达式,这将使 fluentd 能够将多行日志事件聚合到单个消息中。

他们的文档中常见的 java stacktrace 示例:

format multiline format_firstline /\d4-\d1,2-\d1,2/ format1 /^(?<time>\d4-\d1,2-\d1,2 \d1,2:\d1,2:\d1,2) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/

【讨论】:

根据 fluentd 的文档“multiline 仅适用于 in_tail 插件。”这意味着当您使用 @type forward 来自 docker 的输入时,这将不起作用。 @AshBerlin - 你也可以在多个插件中使用它,支持解析的核心插件在这里描述docs.fluentd.org/articles/… @AshBerlin - 另外,也许可以用 in_tcp 替换 in_forward 插件,它们基本上是一样的,只是 in_forward 也侦听 UDP。而in_tcp是开箱即用的支持格式解析器的插件之一 啊,我试试看。知道这一点也可能有助于我们处理容器生成 JSON 的情况,该 JSON 被 docker 以字符串形式放在“日志”字段中 @AshBerlin 我没有走那条路,但我建议你也看看 fluent-plugin-parser。您可以传递来自 docker 实例的所有事件,然后尝试在过滤器中对它们进行多行解析,然后再将它们推出

以上是关于用于多行的 Docker Fluentd 日志记录驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

K8s 中的 Docker + Fluentd 进行日志轮换:Docker 是不是需要知道 Fluentd 的存在?

Docker 容器日志管理Fluentd

fluentd收集Docker stdout日志

centos7下安装docker(18.3docker日志---logging driver---fluentd)

使用Fluentd收集Docker容器日志

万能日志数据收集器 Fluentd - 每天5分钟玩转 Docker 容器技术(91)