在一个项目中,我将slf4j与log4j用作基础日志记录库。
我希望我的日志事件具有注册该事件的包和类名。琐碎的东西:com.project.MyClass。
我知道,通常,我可以使用%c或%C转换字符来实现此目的,但是在这种特定情况下,我不能这样做。我的日志事件必须以特定格式显示一些固定数量的值。我不想在每次对记录器的调用中都写入该特定格式,因此我创建了一个包装器类,该类包含Logger作为静态变量。在这个包装器类中,我创建了必要的方法来以适当的格式登录,例如信息,调试和错误。这是代码示例:
public final class AppLog {
private static final Logger APP_LOGGER = LoggerFactory.getLogger("ApplicationLogger");
public static void info(String... args) {
AppLog.APP_LOGGER.info(LogsUtils.generateLogString(args));
}
...
}
问题在于,当使用%c或%C转换字符时,它们始终将com.project.WrapperClass输出为记录事件的类。考虑上面的代码:
我的AppLog类在Utils包中。我的日志事件始终将Utils.AppLog打印为注册日志的包和类,但我希望它打印称为AppLog类的类名称。它总是打印:
2014-04-04|10:57:16,057|ERROR|utils.AppLog
2014-04-04|10:57:16,060|ERROR|utils.AppLog
2014-04-04|11:11:04,708|INFO |utils.AppLog
我想要这个
2014-04-04|10:57:16,057|ERROR|com.project.domain.Person
2014-04-04|10:57:16,060|ERROR|com.project.dao.PersonDAO
2014-04-04|11:11:04,708|INFO |com.service.PersonService
解决此问题的一种方法是在包装类的每次info方法调用中注入class.getName()。但这对我来说似乎是一个非常肮脏的解决方案。还有其他解决方案可以解决我看不到的问题吗?
Log4j配置:
log4j.appender.APPLICATION=org.apache.log4j.DailyRollingFileAppender
log4j.appender.APPLICATION.file=${log.path}application.log
...
log4j.logger.ApplicationLogger=DEBUG, APPLICATION
log4j.additivity.ApplicationLogger=false
提前致谢。
最佳答案
更新的答案:
抱歉,我没有正确回答这个问题。我以前的回答是完全错误的。
因此,这里的问题是您要实例化始终具有相同名称LoggerFactory
的记录器(使用ApplicationLogger
)。
此记录器无法找到AppLog
对象的调用类,因为没有对它的引用。正如您所说,您可以在每个呼叫中插入记录器名称,但是很难维护。
您可以尝试包装Logger
类。
public final class AppLogger {
private Logger logger;
protected AppLogger(String loggerName) {
this.logger = LoggerFactory.getLogger(loggerName);
}
public static AppLogger getAppLogger(String loggerName) {
return new AppLogger(loggerName);
}
public void info(String... args) {
this.logger.info(LogsUtils.generateLogString(args));
}
...
}
在每个类中,请勿使用
LoggerFactory
,而是您自己的类。private static final AppLogger APP_LOGGER = AppLogger.getLogger(CallingClass.class)
然后像这样登录
APP_LOGGER.info("message");
然后在您的模式布局中使用%c(而不是%C),它应该可以正常工作!