In my cartridge I use an external library that logs with java.util.logging
. I want to redirect the log to SLF4J/logback, but somehow this does not work as I would expect it (logs are empty). Here is the relevant logback configuration:
<appender name="PayPal_LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<File>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder>
<pattern>
[%date{yyyy-MM-dd HH:mm:ss.SSS Z}] %-5level ${intershop.HostName} ${intershop.InstallationID} ${intershop.ServerName} [%mdc{requestsite}] [%mdc{requestapplication}] %logger [%marker] [%mdc{request.type}] [%mdc{session.id}] [%mdc{request.uuid}] "%thread" %msg %ex%n
</pattern>
</encoder>
</appender>
<logger name="com.paypal" additivity="false">
<level value="TRACE" />
<appender-ref ref="Error" />
<appender-ref ref="PayPal_LogFile" />
</logger>
JUL logs in DEBUG
level, DEBUG
level is allowed for com.paypal
and I believe that this should be translated to INFO
in SLF4J
. What's wrong?
I'll answer my own question.
The reason for the trouble is the additivity="false"
property of the logger.
Background: Routing from other logging frameworks to SLF4J is generally easy via the so called bridges unless we speak about JUL. See the details here. ICM implements its own bridge between JUL and SLF4J and there is a subtle bug inside. The logging handler of the ICM is attached to the root level and any appender with additivity="false"
won't work because it will never reach the root level.
The bug seems to be here com.intershop.beehive.core.internal.log.JavaLoggingAdapter
:
handler = new JavaLoggingHandler();
handler.setLevel(Level.ALL);
Logger root = LogManager.getLogManager().getLogger("");
root.addHandler(handler);
I've changed the additivity to true
although I'm not very happy about this and now I can explore the third party logs.