Docker logstash 中多行解析的 syslog 驱动程序

Docker syslog driver with multiline parsing in logstash

我正在通过系统日志驱动程序将我的 docker 日志转发到 logstash。这对普通日志行非常有效,但对多行有问题。我 运行 遇到的问题是 docker 日志转发将系统日志消息格式添加到每个日志行。如果我使用 logstash 过滤器多行(logstash 不推荐),我可以成功组合多行并删除附加行上的系统日志消息......但是,这不是线程安全的。我无法通过 logstash 推荐的输入编解码器使逻辑工作。

例如:

Docker 命令:

docker run --rm -it \
      --log-driver syslog \
      --log-opt syslog-address=tcp://localhost:15008 \
      helloWorld:latest

登录 docker 容器:

Log message A
<<ML>> Log message B
  more B1
  more B2
  more B3
Log message C

logstash 收到的日志

<30>Jul 13 16:04:36 [1290]: Log message A
<30>Jul 13 16:04:37 [1290]: <<ML>> Log message B
<30>Jul 13 16:04:38 [1290]:  more B1
<30>Jul 13 16:04:39 [1290]:  more B2
<30>Jul 13 16:04:40 [1290]:  more B3
<30>Jul 13 16:04:41 [1290]:Log message C

现在,我可以使用以下过滤器根据需要解析所有内容:

logstash 过滤器多行

input { 
  tcp {
   port => 15008
   type => "multiline"
 }
}

filter {
  if ( [type] == "multiline") {
    grok {
      match => { "message" => [
        "^<(?<ignore>\d*)>(?<syslogDateTime>[\S]*)\s\[(?<pid>\d*)\]:.(?<newMessage>[\s\S]*)"
      ]}
    }

    multiline {
      pattern => "^[\s\S]*\<\<[M][L]\>\>"
      negate => true
      what => "previous"
      source => "newMessage"
      stream_identity => "%{host}.%{pid}"
    }
}

这正是我在 logstash 消息中想要的

输出

message: Log message A
message: <<ML>> Log message B more B1 more B2 more B3
message: Log message C

但是,它运行了几分钟...但随后挂起并停止处理

尝试通过 logstash 推荐的编解码器多行使其工作

logstash 编解码器多行

 input { 
      tcp {
       port => 15008
       type => "multiline"
       codec => multiline {
         pattern => "^[\s\S]*\<\<[M][L]\>\>"
         negate => true
         what => "previous"
       }
     }
    }

    filter {
      if ( [type] == "multiline") {
        grok {
          match => { "message" => [
            "^<(?<ignore>\d*)>(?<syslogDateTime>[\S]*)\s\[(?<pid>\d*)\]:.(?<newMessage>[\s\S]*)"
          ]}
        }
    }

它正确地组合了多行,但我现在将这些系统日志消息混合到我的多行消息中

输出

message: Log message A
message: <<ML>> Log message B <30>Jul 13 16:04:38 [1290]: more B1 <30>Jul 13 16:04:39 [1290]: more B2 <30>Jul 13 16:04:40 [1290]: more B3
message: Log message C

如何让编解码器处理输出像过滤器一样?

好的,我通过使用 logstash 编解码器多行并在 grok 匹配后添加另一个过滤器来实现它

    mutate {
      gsub => [
        "message", "<\d*>[\s\S]*?\[\d*\]:.", " "
      ]
    }