从 Java 应用程序登录到 ELK,无需解析日志

Logging from Java app to ELK without need for parsing logs

我想将日志从 Java 应用程序发送到 ElasticSearch,传统的方法似乎是在应用程序 运行 服务器上设置 Logstash,然后让 logstash 解析日志文件(使用正则表达式...!)并将它们加载到 ElasticSearch。

这样做是否有原因,而不是仅仅设置 log4J(或 logback)以将所需格式的内容直接记录到日志收集器中,然后可以将其异步传送到 ElasticSearch?对我来说,必须 fiddle 使用 grok 过滤器来处理多行堆栈跟踪(并在日志解析时燃烧 CPU 周期),这对我来说似乎很疯狂,而应用程序本身可以首先将其记录为所需的格式?

切线相关说明,对于 运行 在 Docker 容器中的应用程序,最好的做法是直接登录到 ElasticSearch,因为只需要 运行 一个进程?

如果你真的想沿着这条路走下去,我的想法是使用类似 Elasticsearch appender (or this one or this other one) 的东西,它将你的日志直接发送到你的 ES 集群。

但是,出于@Vineeth Mohan 提到的相同原因,我建议不要这样做。您还需要问自己几个问题,但主要是如果您的 ES 集群因任何原因(OOM、网络故障、ES 升级等)宕机会发生什么?

存在异步性的原因有很多,其中之一是您的体系结构的健壮性,并且大多数时候这比在日志解析上燃烧几个 CPU 周期重要得多。

另请注意,官方 ES 讨论论坛中有一个关于这个主题的ongoing discussion

我认为从 Log4j/Logback/whatever appender 直接记录到 Elasticsearch 通常是不明智的,但我同意编写 Logstash 过滤器来解析 "normal" 人类可读的 Java 日志也是个坏主意。我在所有可能的地方都使用 https://github.com/logstash/log4j-jsonevent-layout 让 Log4j 的常规文件附加程序生成 JSON 不需要 Logstash 进一步解析的日志。

如果您需要快速解决方案,我已经在此处编写了此附加程序 Log4J2 Elastic REST Appender 如果您想使用它。它能够在将日志事件发送到 Elastic 之前根据时间 and/or 事件数量缓冲日志事件(使用 _bulk API 以便一次性发送所有事件)。它已发布到 Maven Central,因此非常简单。

正如其他人已经提到的那样,最好的方法是将其保存到文件中,然后单独将其发送到 ES。但是,我认为如果您需要 运行 快速获得某些东西,直到您 time/resources 实施最佳方式,这才是有价值的。

还有https://github.com/elastic/java-ecs-logging提供了log4j、log4j2和Logback的布局。它非常高效,而且 Filebeat 配置非常少。

免责声明:我是这个库的作者。