从在 docker 容器中运行的 JVM 应用程序将日志发送到 graylog 的最佳做法是什么?

What's the best practice to send logs to graylog from a JVM application which runs within a docker container?

我正在使用 graylog 作为中央日志记录服务器,我正在使用 gelf log4j2-appender 将日志消息发送到 graylog。这很好用。现在我创建了我的应用程序的 docker 图像,我能够 运行 我的软件作为 docker 容器。

我还使用 docker 登录到 stdout(控制台附加程序)以使应用程序登录到 docker(docker 记录 {containerId})。

现在我问自己是否可以节省 gelf log4j2-appender 并使用 docker log-driver/plugin 来代替 gelf。 (参见 https://docs.docker.com/engine/admin/logging/overview/

这里的最佳实践是什么?我认为使用 docker 日志插件会将整个字符串消息发送到 graylog,而 graylog 需要从中提取元信息该字符串(因此我需要在日志消息中提供此元数据,例如 log_level)。这可能会导致 graylog 端消耗更多资源,并且也不可能配置 docker 仅向 graylog 发送错误消息。这会导致更多的网络流量。使用 log4j2 gelf-appender,我能够在日志消息中提供一些额外的元数据,而无需将其包含在主日志消息中,并且在 graylog 端不需要提取。还可以通过 log_level 配置应将哪些消息发送到 graylog。还是我错了?最好的解决方案是什么,或者将日志发送到 graylog 的每种方式的优缺点是什么?

我建议使用现有的 GELF appender 作为您正在使用的日志记录框架(例如 logstash-gelf),而不是将所有内容记录到标准输出并使用 Docker 的 GELF 日志记录驱动程序。

将适当的 GELF appender 与本机 Java 日志记录框架结合使用,使您能够使用 MDC 等高级功能,用有价值的结构化信息丰富您的日志消息,而无需重新解析这些消息在服务器端收到它们之后。使用 Docker GELF 日志记录驱动程序,您只能逐行接收日志消息,尤其是对于 Java 应用程序,处理起来可能会令人头疼(想想多行堆栈跟踪)。

大多数日志记录框架都支持静态字段,因此您可以 "inject" 例如 Docker 容器的 ID。