ELK 处理来自多个 docker 镜像的多行日志

Posted

技术标签:

【中文标题】ELK 处理来自多个 docker 镜像的多行日志【英文标题】:ELK process multiline logs from multiple docker images 【发布时间】:2016-03-08 15:07:32 【问题描述】:

我在运行 docker 容器的集群中运行 ELK(Elasticsearch、Logstash、Kibana)。这些容器通过 GELF 端点将日志发送到 Logstash。

docker run  --log-driver=gelf --log-opt gelf-address=udp://somehost:12201 -ti    my-app:latest 

然后我在 Logstash 中处理日志。在这里,我想折叠多行消息并将它们合并到一个事件中(在我的例子中是 Java 异常)。我的配置是:

input 
    gelf  

filter
    multiline 
      pattern => "^%TIMESTAMP_ISO8601"
      negate => true
      what => "previous"
      source => "short_message"
      

output 
    stdout  codec => rubydebug 

当我处理来自一个 docker 容器的日志时,它可以完美运行,但是对于两个或更多它不起作用,因为它会折叠两个(或多个)日志流的消息。

我希望,在输入中设置多行将解决问题

input 
    gelf 
      filter
         multiline 
            pattern => "^%TIMESTAMP_ISO8601"
            negate => true
            what => "previous"
         
     

但多行在此设置下无法正常工作(似乎是因为bug)。有什么建议?谢谢。

我正在使用:Docker 1.9.1、Logstash 2.1

【问题讨论】:

【参考方案1】:

我们通过使用多行过滤的选项'stream_identity'解决了这个问题。

流标识是多行过滤器如何确定事件属于哪个流。这通常用于区分来自同一文件输入中的多个文件的事件,或来自 tcp 输入的多个连接。

https://www.elastic.co/guide/en/logstash/current/plugins-filters-multiline.html#plugins-filters-multiline-stream_identity

当您使用 Gelf 时,您可以使用 host 和 container_id 来唯一标识消息:

filter 

  multiline 
    pattern => "^%TIMESTAMP_ISO8601"
    negate => true
    what => "previous"
    source => "short_message"
    stream_identity => "%host.%container_id"
  

【讨论】:

这不会导致性能问题吗?据我了解,当使用多行过滤器时,Logstash 会下降到一个线程,以便消息可以保持有序。 @jmreicha 我认为它确实有影响!顺便说一句,自从我回答以来,我们确实改变了我们为 Java 服务工作的方式。我们使用the logstash logback appender。这是一种完全不同的方法,因此它肯定不能回答最初的问题。我认为应该根据自己的情况选择方法。如果您不发送大量日志,那么多行方法可能就足够了。在我们想要更大的灵活性之前,这是为我们准备的。 感谢您提供更多信息,多行过滤器是迄今为止我发现的最佳方法。

以上是关于ELK 处理来自多个 docker 镜像的多行日志的主要内容,如果未能解决你的问题,请参考以下文章

利用 ELK 搭建 Docker 容器化应用日志中心

利用ELK搭建Docker容器化应用日志中心

k8s~fluentd从kafka到elk

Docker:ELK + kibana 日志收集系统

使用Docker搭建ELK日志搜集系统

Docker 部署ELK 日志分析