TL;DR :如何在ELK日志解析中最好地支持多个多行模式?

随着Docker,Python和ELK的普及,人们会认为将正确解析的Python日志从Docker转换为ELK会非常简单,但我找不到令人满意的方法来做到这一点 .

我有一个docker swarm-mode集群,运行着许多应用程序和服务,包括traefik,nginx,MongoDB,Postgres和许多Python 3服务 . 我有文件收集所有docker日志并将它们直接发送到ES集群 . 除了处理多行输出外,这种方法效果很好 .

Python的多行堆栈跟踪通常看起来像这样(在周围的上下文中):

2018-08-14 06:47:20,390:1:MainThread:INFO:gunicorn.error: Shutting down: Master
2018-08-14 07:15:05,181:9:ThreadPoolExecutor-0_0:ERROR:gunicorn.error: Error handling request /test?text=123&throw=1
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 279, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 328, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/usr/local/lib/python3.6/dist-packages/hug/interface.py", line 100, in __call__
    return __hug_internal_self._function(*args, **kwargs)
  File "/apps/tester/test.py", line 11, in inner
    raise RuntimeError
RuntimeError
2018-08-14 07:15:05,184:9:ThreadPoolExecutor-0_0:INFO:gunicorn.access: 10.255.0.2 - - [14/Aug/2018:07:15:05 +0000] "GET /test?text=123&throw=1 HTTP/1.1" 500 0 "-" "-"
2018-08-14 21:53:20,846:9:MainThread:INFO:gunicorn.error: Worker exiting (pid: 9)

我可以使用以下内容正确解析Python堆栈跟踪:

multiline.pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}:"
multiline.negate: true
multiline.match: after

这样就可以正确地将所有不以时间戳开头的行包装到那些那些但是会使所有非Python日志完全混乱的行 .

我可以从堆栈跟踪中获得合理的多行集合,而不是:

multiline.pattern: "^ |\t"
multiline.negate: false
multiline.match: after

但它将错过堆栈跟踪的最后一行(不缩进) .

如果没有允许其他模式启用(或从中选择)多个潜在多行规则集之一的机制,似乎应对来自不同服务的日志格式混合的唯一方法是不从 /var/lib/docker/containers/*/*.log 收集而是使用Python日志的不同docker日志记录驱动程序 . 我可以将logstash添加到混合中,并通过不同的docker驱动程序将其用于Python日志 . 这样可以正常工作(-ish),因为它允许我有不同的多线模式,但有两个缺点:

1)logstash和filebeat的模板和字段完全不同 .

2)这给了我2个多行模式但是如果我需要3个或更多模式,那么在更多端口上添加更多logstash进程并不是真正可扩展的 .

必须有更好的方法来支持多个多线模式 .

思路:

1)我可以使用另一个探索器从不同的日志位置收集Python容器,但是我找不到让docker的日志驱动程序为某些容器使用不同位置的方法 .

2)我可以使用标签来区分不同类型的日志格式,从而区分多行要求,但filebeat似乎无法在标签上进行过滤 .