0

我正在将 log4j 用于在集群环境中运行的 Web 应用程序。在少数情况下,某些进程(不是特定的)的日志记录会丢失。我无法指出原因。在单个服务器实例上运行时,它工作正常。我正在使用每日滚动文件附加程序。要添加/修改的任何其他属性?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>
4

2 回答 2

1

Without you attaching your Log4J configuration, plus some information about your cluster topology, it is impossible to know for sure, but: what you're describing that could very well happen if there's a mismatch between how you configure Log4J, and how your application is configured to run in a cluster.

For example, if both cluster members run on the same physical machine, and your application is using the very same Log4J configuration file in both instances, then effectively, you have two different JVM's logging into the same files at once. That isn't going to work very well.

Generally speaking, you should avoid a situation in which two different classloaders write into the same physical files.

UPDATE (following attachment of log4j.xml): assuming that your clustered servers run on the same physical machine, the configuration you attached will end up with multiple log4j configurations logging into the same physical files (log4j "lives" in the context of a classloader, and you have multiple servers - hence multiple classloaders, on the same physical machine). This is not going to work, because the two log4j "instances" don't have a way to synchronize writing into that file.

An AsyncAppender isn't going to help you. All that AsyncAppender does is that it buffers the logging requests so your program gets control before the log lines are actually written. It doesn't solve the problem of synchronizing writing into the very same file.

There are two ways to resolve it:

  1. Have each JVM log into a different log file. Actually, give it a shot and witness that it works.
  2. Use a SocketAppender instead. All your logging (from all server instances) will end up being sent over a network connection, and a server program (provided by log4j) will collect them and write them into a file. Explanation how to use it can be found here.
于 2012-12-16T14:39:16.933 回答
1

根据Isaac给出的建议,以避免两个不同的类加载器/jvm 写入同一个物理日志文件的情况:

有两种方法可以解决它:

  1. 让每个 JVM 登录到不同的日志文件中。实际上,试一试并见证它有效

  2. 请改用 SocketAppender。您的所有日志记录(来自所有服务器实例)最终将通过网络连接发送,服务器程序(由 log4j 提供)将收集它们并将它们写入文件。说明如何使用它可以在这里找到。

对于第 1 点,以下方法可以工作:

利用:

<param name="File" value="${sys:log4j.logFile}" />

反而:

 <param name="File" value="/logs/app.log" />

对于 JVM1,设置 JVM 属性:log4j.logFile=/logs/ jvm1 /app.log

对于 JVM2,设置 JVM 属性:log4j.logFile=/logs/ jvm2 /app.log

有关更多详细信息和其他选项:请参阅:link1link2

于 2013-02-15T07:34:21.497 回答