log4j2 : Async logger is NOT starting
I have recently upgraded my application to use log4j2. I am trying to make use of its async logger feature. However looks like its not creating one. As per Log4j Async config, it says,
- To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property Log4jContextSelector to org.apache.logging.log4j.core.async.AsyncLoggerContextSelector. I also set the status="trace" in log4j.xml to see if it configures and instantiate async logger. But looks like it failing.
2017-01-25 01:58:30,799 main TRACE Reregistering context (1/1): 'AsyncContext@18b4aac2' org.apache.logging.log4j.core.async.AsyncLoggerContext@6bf08014 2017-01-25 01:58:30,800 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2' 2017-01-25 01:58:30,800 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=StatusLogger' 2017-01-25 01:58:30,800 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=ContextSelector' 2017-01-25 01:58:30,801 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=Loggers,name=' 2017-01-25 01:58:30,801 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=Appenders,name=' 2017-01-25 01:58:30,801 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=AsyncAppenders,name=' 2017-01-25 01:58:30,801 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=AsyncLoggerRingBuffer' 2017-01-25 01:58:30,802 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=Loggers,name=,subtype=RingBuffer' 2017-01-25 01:58:30,803 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@18b4aac2 2017-01-25 01:58:30,805 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=AsyncLoggerRingBuffer 2017-01-25 01:58:30,806 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=StatusLogger 2017-01-25 01:58:30,807 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@18b4aac2,component=ContextSelector 2017-01-25 01:58:30,816 main TRACE Using default SystemClock for timestamps. 2017-01-25 01:58:30,816 main TRACE Using DummyNanoClock for nanosecond timestamps. 2017-01-25 01:58:30,817 main DEBUG Reconfiguration complete for context[name=AsyncContext@18b4aac2] at URI /etc/opt/sun/im/default/config/log4j2.xml (org.apache.logging.log4j.core.async.AsyncLoggerContext@6bf08014) with optional ClassLoader: null 2017-01-25 01:58:30,817 main DEBUG Shutdown hook enabled. Registering a new one. 2017-01-25 01:58:30,818 main DEBUG LoggerContext[name=AsyncContext@18b4aac2, org.apache.logging.log4j.core.async.AsyncLoggerContext@6bf08014] started OK.
As I don't see anything like "Starting AsyncLogger disruptor".
-
Then as suggested, I tried using asyncLogger tag, I could see it printing,
2017-01-25 00:27:26,970 main TRACE AsyncLoggerConfigDisruptor creating new disruptor for this configuration. 2017-01-25 00:27:26,971 main TRACE property AsyncLoggerConfig.WaitStrategy=TIMEOUT 2017-01-25 00:27:26,987 main DEBUG Starting AsyncLoggerConfig disruptor for this configuration with ringbufferSize=4096, waitStrategy=TimeoutBlockingWaitStrategy, exceptionHandler=org.apache.logging.log4j.core.async.AsyncLoggerConfigDefaultExceptionHandler@7f284218... 2017-01-25 00:27:26,988 main TRACE AsyncLoggerConfig[xmppd] starting...
But again at later stage it throws exception for class not found,
2017-01-25 00:27:31,658 main ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.async.AsyncLoggerConfig for element AsyncLogger. java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:132) at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:942) at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:882) at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:874) at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:498) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:227) at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:239) at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:530) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:603) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620) at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:226) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:242) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45) at org.apache.logging.log4j.LogManager.getContext(LogManager.java:174) at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:618) at org.apache.logging.log4j.LogManager.getRootLogger(LogManager.java:652) Caused by: java.lang.NoClassDefFoundError: com/lmax/disruptor/EventFactory at org.apache.logging.log4j.core.config.AbstractConfiguration.getAsyncLoggerConfigDelegate(AbstractConfiguration.java:197) at org.apache.logging.log4j.core.async.AsyncLoggerConfig.(AsyncLoggerConfig.java:81) at org.apache.logging.log4j.core.async.AsyncLoggerConfig.createLogger(AsyncLoggerConfig.java:188) ... 23 more Caused by: java.lang.ClassNotFoundException: com.lmax.disruptor.EventFactory at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 26 more
I have verified, the disruptor jar which I included has this class. I am using disruptor-3.3.6.jar.
Also How to verify that the async logger has started ?
Any help would be appreciated.
Solution 1:
Add the LMAX Disruptor dependency.To use AsyncLogger, your pom.xml
should be like this
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.7</version>
</dependency>
Further reading : Performance of log4j2 compared to log4j1
Solution 2:
Having tried all the suggestions, I had to look for another solution.
First, make sure you have a file called log4j2.component.properties
in the classpath. ( in the same place you have log4j2 file src/main/resources
)
its content is :
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
Next, verify you have this dependency ( I was getting this Exception in thread "main" java.lang.NoClassDefFoundError: com/lmax/disruptor/EventTranslatorVararg
when I didn't have it)
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.1</version>
</dependency>