I've stucked on Log4j2 XML configuration for a while and cannot figure out how to write to file by RollingFile and RollingRandomAccessFile appenders.
When I launch log4j2 it successfully initializes, writes log to console with console appender and System.out.println(). But when I do tail -f logs/error.log
or less logs/error.log
I don't see it in real time.
But after I kill -9 $jarpid
it immediately writes to log file so I can see it in tail. I thought that tail could block file, but it doesn't. I've read file in runtime by nano logs/error.log
, it was empty and text appeared there only after killing proccess. I've mentioned thet it could be because I use RollingRandomAccessFile, may be I experience this "randomness". But RollingFile acts the same.
I've tryed to write do another file (who knows, may be it's used by another app already). Same thing.
Realy confused now and cannot figure it out.
Here is my 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>
Here is my java app:
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);
}
}
}
Per the log4j2 manual the RollingFileAppender
parameter immediateFlush
is described as follows:
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.
You have this parameter set to false
in your configuration which means data is not written to the disk after each write. If you want each write to be followed by a flush to disk then set this parameter to true
instead.