Log4j输出完整的类名和包

时间:2014-04-04 11:11:41

标签: java logging log4j slf4j

在一个项目中,我使用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

提前致谢。

1 个答案:

答案 0 :(得分:1)

更新的答案:

抱歉,我没有得到正确的答案。我之前的回答是完全错误的;

因此,您的问题是您正在使用始终具有相同名称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),它应该按预期工作!