I want to retrofit slf4j with Logback into a legacy application. Good thing is, the legacy application has its own logging framework. So all I had to do is alter the logging framework to log to slf4j instead of log4j.
It worked like a dream. I was happy, until I noticed the location Logback logged for each and every log event:
Logger.java:...
Yikes! That wasn't going to help my fellow developers much when trying to figure out where a log event came from.
How can I tell Logback to look a few levels up in the stack for the actual location to log?
The logger class is a utility class with methods like this:
public static void debug(String clazz, String message) {
org.slf4j.Logger logger = LoggerFactory.getLogger(clazz);
logger.debug(message);
}
Found the solution looking at the source of jcl-over-slf4j
. Most implementations of slf4j (including logback) use loggers that implement LocationAwareLogger
, which has a log method that expects the fully qualified class name of the wrapping logger class as one of it's arguments:
private static final String FQCN = Logger.class.getName();
public static void debug(String clazz, String message) {
org.slf4j.Logger logger = LoggerFactory.getLogger(clazz);
if (logger instanceof LocationAwareLogger) {
((LocationAwareLogger) logger).log(null, FQCN, LocationAwareLogger.DEBUG_INT, message, null, null);
} else {
logger.debug(message);
}
}
See the various XXX-over-slf4j implementations for how to do it.
Basically you want to replace your current logger framework completely. Not wrap slf4j.
Edit:
Another approach could be writing your own layout subclassing the one you use now, which has a revised meaning of the %m, %l etc fields which skips the extra stack frame.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With