问题
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);
}
回答1:
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);
}
}
回答2:
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.
来源:https://stackoverflow.com/questions/3491744/wrapping-the-slf4j-api