自定义SLF4J Wrapper没有在日志文件中打印正确的方法名称



我有一个自定义的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等。我猜这是因为自定义记录器在该类中使用包装器方法,但为什么会出现这种行为,是否有方法可以修复此问题。

包装器日志记录器是设计的,由于一些内部原因我们无法避免它。

Log4j使用在堆栈跟踪中查找固定数量的步骤来查找调用类。

Log4j包含一个生成Logger包装器的工具:http://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

请看看这个工具(源代码在这里),因为它解决了同样的问题。诀窍是将正确的FQCN(完全限定类名)传递给ExtendedLoggerWrapper.logIfEnabled方法。

最新更新