我从slf4j Logger类创建了一个装饰类,因为我需要在info、debug等方法中执行特定的检查。我正在使用log4j12绑定。
除了日志记录的FQCN之外,它工作得很好:它不是调用类的FQCN,而是装饰类的FQCN。
package foo.bar;
import org.slf4j.Logger;
public class MyLogger implements Logger {
private final Logger logger;
private final boolean traceAndExit;
public MyLogger(Logger logger, boolean traceAndExit) {
this.logger = logger;
this.traceAndExit = traceAndExit;
} // MyLogger
@Override
public void info(String message) {
try {
logger.info(message);
} catch (Exception e) {
if (traceAndExit) {
traceAndExit(e);
} // if
} // catch
} // info
...如果在任何其他类foo.bar.OtherClass中,我会这样做:
MyLogger myLogger = new MyLogger(LoggerFactory.getLogger(OtherClass.class), true);
myLogger.info("this is a message");然后,我获得的日志打印foo.bar.MyLogger而不是foo.bar.OtherClass (%C转换字符)。
知道该怎么做吗?这是强制性的,我打印FQCN。
发布于 2015-03-17 08:08:36
不幸的是,您没有提到您使用的日志记录实现。slf4j只是各种日志工具共享的一个公共API。
幸运的是,至少Logback、Log4j和Log4j 2 --它们应该是野生日志实现者中的大多数--以同样的方式解释%C格式说明符。
登录文档和Log4j 2文档将%C定义为“发出日志请求的调用方的完全限定类名”。这种情况发生在ch.qos.logback.classic.spi.CallerData和org.apache.logging.log4j.util.ReflectionUtil中。基本上,框架会检查堆栈跟踪,直到他们合理地确定留下了自己的代码基,然后使用他们在堆栈上遇到的"next“类。在您的例子中,这是MyLogger类。
避免这种情况的最容易的方法是完全放弃%C格式说明符。虽然在调试中很有用,但堆栈内省会对性能产生严重影响,并且无法干净地处理像您这样的情况。
%c格式说明符将插入记录器的名称。如果您正确地初始化记录器:
// static logger
private static final Logger STATIC_LOG = LoggerFactory.getLogger(OtherClass.class);
// instance logger
private final Logger log = LoggerFactory.getLogger(getClass());%c产生预期的输出。这还允许高级日志解决方案,例如每类多个记录器用于审计日志记录。
如果您必须使用%C说明符,则Logback提供一个选项来设置调用方扫描忽略的框架包:
// during application startup
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.getFrameworkPackages().add("foo.bar.logging")请注意,这将有效地禁用整个foo.bar.logging包的foo.bar.logging输出。Log4j 2似乎没有提供类似的配置选项。
https://stackoverflow.com/questions/29093144
复制相似问题