I'm trying to migrate my app into using log4j2. It is currently using log4j 1.2.16. I also have a performance build for my project, and after upgrading to log4j 2, the performance seemed to have improve a lot.
That is, until I read about bridging. According to the doc, I have to exclude log4j1 JAR from the classpath, and include the bridging JAR - which I assume is named 'org.apache.logging.log4j:log4j-1.2-api'. Once I did this, performance dropped again.
So to summarise:
- Performance with log4j2 + bridging jar + log4j-1.2-api + log4j1 : good
- Performance with log4j2 + bridging jar + log4j-1.2-api : bad (to the point that it drops back to performance of just log4j1)
I have checked that the log4j-1.2-api is earlier in the classpath. So it should have been loaded first.
Any idea what could cause this problem?
Thank you very much in advance!
Oh my complete classpath for logging are:
- org.slf4j:slf4j-api
- org.slf4j:log4j-over-slf4j
- org.slf4j:jcl-over-slf4j
- org.apache.logging.log4j:log4j-slf4j-impl
- org.apache.logging.log4j:log4j-core
- org.apache.logging.log4j:log4j-api
- org.apache.logging.log4j:log4j-1.2-api
- log4j:log4j (with & without, as described above)
Versions:
- Log4j2 : 2.6.2
- slf4j: 1.7.20
- log4j1: 1.2.16
My config file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="log4j2-xinclude-appenders.xml" />
<Loggers>
<Root level="info">
<AppenderRef ref="rollingFileAppender"/>
<AppenderRef ref="stdOutAppender"/>
</Root>
</Loggers>
</Configuration>
And the log4j2-xinclude-appenders.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<appenders>
<RollingRandomAccessFile name="_rollingFileAppender" fileName="./logs/foo-${sys:app.name.suffix}.log"
filePattern="./logs/foo-${sys:foo.app.name.suffix}.log.%i">
<PatternLayout>
<Pattern>%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy minSize="0" />
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingRandomAccessFile>
<Async name="rollingFileAppender" blocking="false" bufferSize="10000">
<AppenderRef ref="_rollingFileAppender"/>
</Async>
<Console name="_stdOutAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n"/>
</Console>
<Async name="stdOutAppender" blocking="false" bufferSize="10000">
<AppenderRef ref="_stdOutAppender"/>
</Async>
</appenders>
EDIT: This is the log4j 1 xml file that gets included in the classpath
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<appender name="R" class="com.bar.common.util.RollingFileAppender">
<param name="File" value="./logs/bar.log"/>
<param name="MaxFileSize" value="100MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<!-- Performance Appender -->
<appender name="OneSecondStatsAppender"
class="com.foo.perf.AggregatedStatisticsAppender">
<param name="TimeSlice" value="1000"/>
<appender-ref ref="OneSecondStatsLogger"/>
</appender>
<appender name="FiveMinuteStatsAppender"
class="com.bar.perf.DatafabricAggregatedStatisticsAppender">
<param name="TimeSlice" value="300000"/>
<appender-ref ref="FiveMinuteStatsLogger"/>
</appender>
<!-- Aggregated Performance Statistics Appender -->
<appender name="OneSecondStatsLogger" class="org.apache.log4j.FileAppender">
<param name="File" value="./logs/bar-performance.log"/>
<layout class="com.bar.perf.AggregatedStatisticsCsvLayout"/>
<filter class="com.bar.perf.CategorisedStatisticExclusionFilter"/>
</appender>
<appender name="FiveMinuteStatsLogger" class="org.apache.log4j.FileAppender">
<param name="File" value="./logs/bar-minutes.log"/>
<layout class="com.bar.perf.AggregatedStatisticsCsvLayout">
<param name="ShowEmptyStatistics" value="true"/>
</layout>
</appender>
<!-- Loggers -->
<logger name="org.perf4j.TimingLogger" additivity="false">
<level value="INFO"/>
<appender-ref ref="OneSecondStatsAppender"/>
<appender-ref ref="FiveMinuteStatsAppender"/>
</logger>
<logger name="com.bar">
<level value="INFO"/>
</logger>
<logger name="com.gemstone.gemfire">
<level value="INFO"/>
</logger>
<logger name="org.springframework.data">
<level value="INFO"/>
</logger>
<!-- Root logger configuration -->
<root>
<priority value="INFO"/>
<appender-ref ref="R"/>
</root>
</log4j:configuration>
EDIT 2: Classpath order for poor performance:
log4j-1.2-api-2.6.2.jar
jcl-over-slf4j-1.7.20.jar
slf4j-api-1.7.20.jar
log4j-slf4j-impl-2.6.2.jar
log4j-core-2.6.2.jar
log4j-api-2.6.2.jar
log4j-1.2.16.jar
Classpath order for good performance
log4j-1.2-api-2.6.2.jar
jcl-over-slf4j-1.7.20.jar
slf4j-api-1.7.20.jar
log4j-over-slf4j-1.7.20.jar
log4j-slf4j-impl-2.6.2.jar
log4j-core-2.6.2.jar
log4j-api-2.6.2.jar
log4j-1.2.16.jar