我有一个自定义SLF4J
包装器,如下所示:
Logger.java
public final class Logger {
private final org.slf4j.Logger slf4jLogger;
public Logger() {
this.slf4jLogger = com.demo.LoggerFactory.DEFAULT_LOGGER;
}
public Logger(final org.slf4j.Logger slf4jLogger) {
this.slf4jLogger = slf4jLogger;
}
public void debug(final String message, final Object... args) {
if (isDebugEnabled()) {
slf4jLogger.debug(message, args);
}
}
// ... other logger methdods
}
LoggerFactory.java
public class LoggerFactory {
public static final org.slf4j.Logger DEFAULT_LOGGER = org.slf4j.LoggerFactory.getLogger(AppSupportConstants.DEFAULT_LOGGER);
public static Logger getLogger(final Class<?> clazz) {
if (clazz != null) {
return new Logger(org.slf4j.LoggerFactory.getLogger(clazz));
}
return new Logger(DEFAULT_LOGGER);
}
}
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Properties>
<Property name="logFilePath">logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [Thread: %t] %level{length=1} %c{1.}.%M - %msg%n" />
</Console>
<RollingRandomAccessFile name="APP_LOG_APPENDER" fileName="${catalina.base}/logs/demo.log"
filePattern="logs/$${date:yyyy-MM}/demo-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread: %t] %level{length=1} %c{1.}#%M - %msg%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Logger name="DEFAULT_LOGGER" level="debug" additivity="false">
<AppenderRef ref="APP_LOG_APPENDER" />
</Logger>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="APP_LOG_APPENDER" />
</Root>
</Loggers>
</Configuration>
LogDemo.java
public class LogDemo {
// SLF4J Logger
private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LogDemo.class);
// Custom Logger
private static final Logger customLogger = LoggerFactory.getLogger(LogDemo.class);
public static void main(final String[] args) {
new LogDemo().demo();
}
public void demo() {
logger.debug("[Direct] Debug...");
logger.info("[Direct] Info...");
logger.warn("[Direct] Warn...");
logger.error("[Direct] Error...");
customLogger.debug("[CustomLogger] Debug...");
customLogger.info("[CustomLogger] Info...");
customLogger.warn("[CustomLogger] Warn...");
customLogger.error("[CustomLogger] Error...");
}
}
输出上述代码
2015-10-09 16:45:07.642 [Thread: main] D c.d.LogDemo#demo - [Direct] Debug...
2015-10-09 16:45:07.644 [Thread: main] I c.d.LogDemo#demo - [Direct] Info...
2015-10-09 16:45:07.644 [Thread: main] W c.d.LogDemo#demo - [Direct] Warn...
2015-10-09 16:45:07.644 [Thread: main] E c.d.LogDemo#demo - [Direct] Error...
2015-10-09 16:45:07.645 [Thread: main] D c.d.LogDemo#debug - [CustomLogger] Debug...
2015-10-09 16:45:07.646 [Thread: main] I c.d.LogDemo#info - [CustomLogger] Info...
2015-10-09 16:45:07.646 [Thread: main] W c.d.LogDemo#warn - [CustomLogger] Warn...
2015-10-09 16:45:07.646 [Thread: main] E c.d.LogDemo#error - [CustomLogger] Error...
如果您注意到,customLogger
打印的记录器语句显示的方法名称为debug
,info
等。我想这是因为自定义记录器在该类中使用了包装器方法,但为什么这样的行为,有没有办法解决这个问题。
包装记录器是设计使然,由于某些内部原因我们无法避免它。
答案 0 :(得分:0)
Log4j使用在堆栈跟踪中查找固定数量的步骤来查找调用类。
Log4j包含一个用于生成Logger包装器的工具:http://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers
请查看此工具(source code here),因为它解决了同样的问题。诀窍是将正确的FQCN(完全限定类名)传递给ExtendedLoggerWrapper.logIfEnabled
方法。