在 java 程序中断之前,Log4j2 不会写入文件

Log4j2 doesn't write to file until java programm interrupted

我在 Log4j2 XML 配置上停留了一段时间,无法弄清楚如何通过 RollingFile 和 RollingRandomAccessFile appender 写入文件。

当我启动 log4j2 时,它成功初始化,使用控制台附加程序和 System.out.println() 将日志写入控制台。但是当我执行 tail -f logs/error.logless logs/error.log 时,我不会实时看到它。 但是在我 kill -9 $jarpid 之后它立即写入日志文件所以我可以在尾部看到它。我以为 tail 可以阻止文件,但事实并非如此。我已经通过 nano logs/error.log 在运行时读取了文件,它是空的,只有在终止进程后才会出现文本。我已经提到它可能是因为我使用 RollingRandomAccessFile,可能是我遇到了这个 "randomness"。但是 RollingFile 的行为是一样的。 我试着写另一个文件(谁知道,可能它已经被另一个应用程序使用了)。同样的事情。

现在很迷茫,想不通

这是我的 log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <RollingFile name="ErrorFile"
                                 fileName="logs/error.log"
                                 filePattern="logs/error-%d{MM-dd-yyyy}-%i.log.zip"
                                 immediateFlush="false"
                                 append="true"
                                 ignoreExceptions="false">
            <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%-5level] %d{dd.MM.yyyy HH:mm:ss} - %logger{36} - %msg%n" disableAnsi="false"/>
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="250 MB"/>
            </Policies>
        </RollingFile>
    <Console name="Console" target="SYSTEM_OUT" follow="true" ignoreExceptions="true">
        <PatternLayout pattern="[%highlight{%-5level}] %d{dd.MM.yyyy HH:mm:ss} - %logger{36} - %msg%n" disableAnsi="false"/>
    </Console>
</Appenders>
    <Loggers>
        <Root level="all" includeLocation="false">
            <AppenderRef ref="ErrorFile"/>
        </Root>
    </Loggers>
</Configuration>

这是我的 java 应用程序:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class test {
    public static Logger log = LogManager.getLogger(test.class);
    public static void main(String[] args) throws Exception{
        while (true) {
            log.debug("debug");
            log.error("error");
            System.out.println("JAR WORKS!"+System.currentTimeMillis());
            Thread.sleep(10000);
        }
    }
}

根据log4j2 manual RollingFileAppender参数immediateFlush描述如下:

When set to true - the default, each write will be followed by a flush. This will guarantee the data is written to disk but could impact performance.

Flushing after every write is only useful when using this appender with synchronous loggers. Asynchronous loggers and appenders will automatically flush at the end of a batch of events, even if immediateFlush is set to false. This also guarantees the data is written to disk but is more efficient.

您在配置中将此参数设置为 false,这意味着数据不会在每次写入后写入磁盘。如果您希望每次写入后都刷新到磁盘,请将此参数设置为 true