2

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>
Loganathan Mohanraj
  • 1,736
  • 1
  • 13
  • 22
  • 1
    Which version of pax-logging are you using? I've done major refactoring with version 1.11.x (and 2.0.x) and "status logger" is integrated with default logger of pax-logging itself. and log4j2's "status" logger's level is determined by `org.ops4j.pax.logging.DefaultServiceLog.level` system or context property. Check new [wiki page](https://ops4j1.jira.com/wiki/spaces/paxlogging/pages/499286109/Configuration) for configuration details. – Grzegorz Grzybek May 26 '20 at 06:05
  • 1
    For "async", you have to set `org.ops4j.pax.logging.log4j2.async` property and ensure that `com.lmax.disruptor.EventFactory` class is available. See [this code fragment](https://github.com/ops4j/org.ops4j.pax.logging/blob/logging-1.11.4/pax-logging-log4j2/src/main/java/org/ops4j/pax/logging/log4j2/internal/PaxLoggingServiceImpl.java#L259-L270), though I confess I didn't check asynchronous processing much. Feel free to contribute ;) – Grzegorz Grzybek May 26 '20 at 06:08
  • @GrzegorzGrzybek, it is version 1.11.3. I haven't attempted to change this property - org.ops4j.pax.logging.DefaultServiceLog.level. Let me check and get back. – Loganathan Mohanraj May 26 '20 at 06:27
  • org.ops4j.pax.logging.log4j2.async=true is set as well – Loganathan Mohanraj May 26 '20 at 06:28
  • Setting org.ops4j.pax.logging.DefaultServiceLog.level to DEBUG helps. Any idea how to resolve the logs out of order in asynchronous logging. Thanks – Loganathan Mohanraj May 26 '20 at 06:38
  • I'm afraid I don't have clear answer now... I didn't have time to check thoroughly the async aspects of Log4j2 in pax logging... But if you provide some sample github project where I can see it (to save me the time to prepare reproducer), I could have a look at it. – Grzegorz Grzybek May 26 '20 at 08:41
  • @GrzegorzGrzybek, log event time stamp order issue happens only in a scaled environment. I have to create a sample code to reproduce the issue. Issue here is, log4j2 is not picking the VM argument -Dlog4j2.AsyncQueueFullPolicy=Enqueue -DAysncLogger.RingBufferSize=4194304. Is there any alternate way to configure these parameters in ODL – Loganathan Mohanraj May 26 '20 at 13:44
  • Thanks for hint about these arguments. I can check why they're not passed from sysprops. BTW - do you have LMAX library on your classpath? in bootclasspath? ext? – Grzegorz Grzybek May 27 '20 at 04:39
  • @GrzegorzGrzybek, Yes. LMAX disruptor is installed in karaf. I have even tried to add lmax disruptor in startup.properties as well but no help. Added the exception trace in question. – Loganathan Mohanraj May 27 '20 at 17:19
  • @GrzegorzGrzybek, sample code to simulate the log out of order is pushed in github - https://github.com/logumohan/log-out-of-order. – Loganathan Mohanraj May 29 '20 at 19:07
  • Thanks for the code - checking now. – Grzegorz Grzybek Jun 05 '20 at 11:25
  • Hmm (I had power outage) this project has nothing related to pax-logging and if you think it's a problem (with your code example) then it looks like a problem with Log4j2 itself. – Grzegorz Grzybek Jun 05 '20 at 13:29

0 Answers0