I have recently upgraded log4j2 in my application. It is running on top of the open day light controller. The pax-logging-log4j2 (version 1.11.3) bundle is added to the karaf start up bundles. With Log4J2, I have enabled the asynchronous logging as well. The below VM argument is added in the karaf start up script for enabling asynchronous logging.
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=Sleep
Application logging is working as expected but sometimes, the logs are not in order (timestamps are overlapped). To resolve this, I have tried to set AsyncQueueFullPolicy to ENQUEUE and RingBufferSize to 4098*1024 but no luck.
-Dlog4j2.AsyncQueueFullPolicy=Enqueue
-DAysncLogger.RingBufferSize=4194304
Tried to enable Log4J2 status logger (as like below) but the logs are not getting logged.
status=debug is added the "org.ops4j.apache.pax.logging.cfg" file.
Couple of issues, log4j2 status logger is not logged and application logs are not in order.
Any help here would be of great help.
EDIT: Further analysis of the status logger shows asynchronous logging is reverted to synchronous with reason "com.lmax.disruptor.EventFactory cannot be found".
org.ops4j.pax.logging.pax-logging-api [log4j2] WARN : Asynchronous loggers defined, but the disruptor library is not available. Reverting to synchronous loggers. Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
java.lang.ClassNotFoundException: com.lmax.disruptor.EventFactory cannot be found by org.ops4j.pax.logging.pax-logging-log4j2_1.11.3
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:439)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:352)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:344)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:160)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.ops4j.pax.logging.log4j2.internal.PaxLoggingServiceImpl.updated(PaxLoggingServiceImpl.java:263)
at org.ops4j.pax.logging.log4j2.internal.PaxLoggingServiceImpl$1ManagedPaxLoggingService.updated(PaxLoggingServiceImpl.java:581)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updated(ManagedServiceTracker.java:189)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updateService(ManagedServiceTracker.java:152)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.provideConfiguration(ManagedServiceTracker.java:85)
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.provide(ConfigurationManager.java:1463)
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.run(ConfigurationManager.java:1419)
at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:141)
at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:109)
at java.lang.Thread.run(Thread.java:748)
Added "pax-logging-log4j2-extra" in startup.properties and the dependency issues are resolved.
AsyncLoggerContext is created now.
org.ops4j.pax.logging.pax-logging-api [log4j2] DEBUG : Starting LoggerContext[name=pax-logging, org.apache.logging.log4j.core.async.AsyncLoggerContext@1eb9a021] with configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration@3810215b... Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
but it is not picking the custom AsyncQueueFullPolicy added in the VM argument.
-Dlog4j2.AsyncQueueFullPolicy=a.b.c.d.BlockingQueueFullPolicy
Logs:
org.ops4j.pax.logging.pax-logging-api [log4j2] DEBUG : Using DefaultAsyncQueueFullPolicy. Could not create custom AsyncQueueFullPolicy 'a.b.c.d.BlockingQueueFullPolicy': java.lang.ClassNotFoundException: com.fujitsu.fnc.sdnfw.async.BlockingQueueFullPolicy cannot be found by org.ops4j.pax.logging.pax-logging-api_1.11.3 Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
Created a fragment bundle with the below custom policy and installed it in karaf.
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.async.AsyncQueueFullPolicy;
import org.apache.logging.log4j.core.async.EventRoute;
public class BlockingQueueFullPolicy implements AsyncQueueFullPolicy {
public BlockingQueueFullPolicy() {
// Don't Delete. Default constructor is required
}
@Override
public EventRoute getRoute(long backgroundThreadId, Level level) {
return EventRoute.ENQUEUE;
}
}
and pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>a.b.c.d.fw-async-policy-api</Bundle-SymbolicName>
<Bundle-Name>Custom Async Queue Full Policy API</Bundle-Name>
<Bundle-Vendor>XYZ</Bundle-Vendor>
<Bundle-ActivationPolicy>eager</Bundle-ActivationPolicy>
<Embed-Transitive>
false
</Embed-Transitive>
<Export-Package>
a.b.c.d
</Export-Package>
<Fragment-Host>system.bundle; extension:=framework</Fragment-Host>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.slf4j.impl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.slf4j.impl.version}</version>
</dependency>
</dependencies>