假设我在Docker中部署了一个Java Web应用程序,其中有几个组件在容器内生成日志:
STDOUT
和STDERR
server.log
gc.log
应用程序日志被路由到Splunk,但是我们应该如何检索其他组件的日志?
似乎至少有两个选择:
STDOUT
。这是不理想的,因为这会混合日志并产生更难以分离的输出,因为不同的组件会产生不同格式的日志。 server.log
和gc.log
,并将它们通过管道传递到STDOUT
。更好,但这会对磁盘使用产生重大影响。 有更好的解决方案吗?
最佳答案
TLDR;不要混用日志流,使用Sidecar是更好的解决方案,并且对磁盘使用率没有“重大影响”。使用边车将日志重定向到stdout,并依靠容器生态系统读取单个容器日志的能力。
注意:具有日志重定向逻辑的Sidecar不会产生大量开销。我引用Kubernetes documentation来支持此操作-“重定向日志的逻辑极小,因此开销不大”
关键是不要混淆日志流,因为如果不是不可能的话,以后从混合日志流中分离单个流可能是乏味的(带有跨多行的异常堆栈跟踪之类的日志事件)。例如,如果您混合了日志流,则要分析GC,您需要先将GC日志事件单独分离出来,然后再将其输入到您选择的工具中。
解决方案是使用side-car pattern,并带有示例here进行详细说明
关注Single Responsibility Principle。每个sidecar尾部都有一个日志文件,并将其流式传输到stdout。为了实现这一点,所有小汽车都应该可以访问webapp容器的日志卷挂载(例如/ var / log),并且webapp应该将其所有日志写入共享卷挂载。
该Web应用程序会将自己的日志写入stdout(通过LogBack或Log4j的ConsoleAppender说)以及共享卷挂载下的任何其他其他日志文件(例如/ var / log)。例如,对于GC日志,设置JVM参数,以使日志在共享卷挂载-Xloggc:/var/log/mywebapp/gc.log
下生成。
对于每个其他日志文件,您都需要将sidecar尾部(重定向)日志记录到stdout。因此,在您的情况下,您将需要三个辅助工具,一个用于gc.log,一个用于server.log,另一个用于/ var / log / syslog
下面给出了示例性边车集装箱定义摘录。
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/mywebapp/gc.log']
volumeMounts:
- name: varlog
mountPath: /var/log
上面的示例显示了一个从/ var / log共享卷安装到stdout的重定向/尾部日志文件的单个sidecar定义。该示例是从this Kubernetes documentation复制而来的。关于java - 如何从单个Docker容器捕获多个日志流?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60452635/