Send/redirect/route java.util.logging.Logger (JUL) to Logback using SLF4J?
Asked Answered
P

1

36

Is it possible to have a typical call to java.util.logging.Logger and have it route to Logback using SLF4J? This would be nice since I wouldn't have to refactor the old jul code line by line.

EG, say we have this line:

private static Logger logger = Logger.getLogger(MahClass.class.getName());
//...
logger.info("blah blah blah");

It would be nice to configure this to call through SLF4J.

Philologian answered 16/5, 2011 at 16:41 Comment(4)
Yes, it is possible. And it is very easy, you don't have to change any source code. You only must change some .jar libraries. Look at this articles - logging-with-slf4j - legacy logging - SLF4J loggingPatriarchate
There is one major benefit by biting the bullet and refactor to slf4j. Namely that you can use {} in your strings to delay toString() calls.Lechery
Is toString() really a concern with modern JVMs? I realize it is more efficient to avoid toString() calls, but my understanding is that object creation is cheap and that this would fall under premature optimization.Acetic
yes it is really is a concern if you are making rich logging statements. profiling a production system in 2015 on a modern jvm unnecessary calls to create strings for debug statements that are not actual enabled in production is a cpu hotspot for the production system.Fistula
F
62

It's very easy and not a performance issue anymore.

There are two ways documented in the SLF4J manual. There are also precise examples in the Javadocs

Add jul-to-slf4j.jar to your classpath. Or through maven dependency:

<dependency>
    <groupId>org.slf4j</groupId>
     <artifactId>jul-to-slf4j</artifactId>
    <version>1.7.0</version>
</dependency>

If you don't have logging.properties (for java.util.logging), add this to your bootstrap code:

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

If you have logging.properties (and want to keep it), add this to it:

handlers = org.slf4j.bridge.SLF4JBridgeHandler

In order to avoid performance penalty, add this contextListener to logback.xml (as of logback version 0.9.25):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <!-- reset all previous level configurations of all j.u.l. loggers -->
        <resetJUL>true</resetJUL>
    </contextListener> 

    ...

</configuration>
Febrifugal answered 5/12, 2013 at 18:0 Comment(4)
Just a note - I had to reload Logback configuration to make this working for me.Slavocracy
Adding the contextListener configuration was necessary anyway to propagate the logback configuration to the jul logger. So regardless of the performance improvement it was necessary for us.Rossini
It may be related to that bug in some way : jira.qos.ch/browse/LOGBACK-404 i.e. without the propagator Logger are not kept and then their level reset.Rossini
add this to your bootstrap code spring's bootstrap-code is not used in war-archive for deployment.Rileyrilievo

© 2022 - 2024 — McMap. All rights reserved.