我正在将log4j用于在群集环境中运行的Web应用程序。在少数情况下,某些进程(非特定)会丢失日志记录。我无法确定原因。在单个服务器实例上运行时,它可以正常工作。我正在使用每日滚动文件appender。是否要添加/修改任何其他属性? Async Appender会有帮助吗?对此有何解决方案?
编辑:以下是log4j XML以及我计划使用的AsyncAppender
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="appLog" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/logs/app.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="DEBUG" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p (%F:%L) - %m%n" />
</layout>
</appender>
<appender name="async" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="256" />
<param name="LocationInfo" value="true"/>
<appender-ref ref="appLog" />
</appender>
<root>
<priority value="debug" />
<appender-ref ref="async" />
</root>
</log4j:configuration>
答案 0 :(得分:1)
如果没有附加Log4J配置,加上有关群集拓扑的一些信息,则无法确切地知道,但是:如果配置Log4J的方式与如何配置不匹配,那么您所描述的内容很可能会发生您的应用程序配置为在群集中运行。
例如,如果两个集群成员在同一台物理计算机上运行,并且您的应用程序在两个实例中使用的是相同的Log4J配置文件,那么实际上,您有两个不同的JVM登录到同一个文件。这不会很好。
一般来说,你应该避免两个不同的类加载器写入相同的物理文件的情况。
更新(在log4j.xml
附件之后):假设您的群集服务器在同一台物理计算机上运行,您附加的配置最终会有多个log4j配置登录到同一个物理文件(log4j“生活”在类加载器的上下文中,并且在同一台物理计算机上有多个服务器 - 因此有多个类加载器)。这不会起作用,因为两个log4j“实例”没有办法将写入同步到该文件中。
AsyncAppender
无法帮助您。 AsyncAppender
所做的就是它缓冲日志记录请求,以便程序在实际写入日志行之前获得控制。它没有解决将写入同步到同一个文件的问题。
有两种解决方法:
SocketAppender
。所有日志记录(来自所有服务器实例)最终都将通过网络连接发送,服务器程序(由log4j提供)将收集它们并将它们写入文件。可以在here找到解释如何使用它。答案 1 :(得分:1)
根据 Isaac 给出的建议,以避免两个不同的类加载器/ jvm写入同一物理日志文件的情况:
有两种解决方法:
让每个JVM登录到不同的日志文件中。实际上,试一试并证明它有效
- 醇>
请改用SocketAppender。所有日志记录(来自所有服务器实例)最终都将通过网络连接发送,并且a 服务器程序(由log4j提供)将收集并编写它们 到一个文件。解释如何使用它可以在这里找到。
对于第1点,下面的方法可以起作用:
使用:
<param name="File" value="${sys:log4j.logFile}" />
相反:
<param name="File" value="/logs/app.log" />
对于JVM1,设置JVM属性: log4j.logFile = /日志/的 jvm1 强> /app.log
对于JVM2,设置JVM属性: log4j.logFile = /日志/的 JVM2 强> /app.log