我正在运行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
答案 0 :(得分:7)
我们使用选项' stream_identity'解决了这个问题。 多行过滤。
流标识是多行过滤器确定事件属于哪个流的方式。这通常用于区分来自同一文件输入中的多个文件的事件,或来自tcp输入的多个连接。
当您使用Gelf时,您可以使用host和container_id来唯一标识消息:
filter {
multiline {
pattern => "^%{TIMESTAMP_ISO8601}"
negate => true
what => "previous"
source => "short_message"
stream_identity => "%{host}.%{container_id}"
}
}