Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Log4j输出完整的类名和包_Java_Logging_Log4j_Slf4j - Fatal编程技术网

Java Log4j输出完整的类名和包

Java Log4j输出完整的类名和包,java,logging,log4j,slf4j,Java,Logging,Log4j,Slf4j,在一个项目中,我使用slf4j和log4j作为底层日志库。 我希望日志事件具有注册事件的包和类名。一些琐碎的东西,比如:com.project.MyClass 我知道,通常情况下,我可以使用%c或%c转换字符来实现这一点,但在这种特定情况下,我不能。我的日志事件必须以特定格式显示一些固定数量的值。我不想在每次调用记录器时都编写特定的格式,所以我创建了一个包装器类,将记录器作为静态变量包含。在这个包装类中,我创建了必要的方法,以适当的格式登录,如info、debug和error。以下是代码示例:

在一个项目中,我使用slf4j和log4j作为底层日志库。 我希望日志事件具有注册事件的包和类名。一些琐碎的东西,比如:com.project.MyClass

我知道,通常情况下,我可以使用%c或%c转换字符来实现这一点,但在这种特定情况下,我不能。我的日志事件必须以特定格式显示一些固定数量的值。我不想在每次调用记录器时都编写特定的格式,所以我创建了一个包装器类,将记录器作为静态变量包含。在这个包装类中,我创建了必要的方法,以适当的格式登录,如info、debug和error。以下是代码示例:

    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

提前谢谢

更新答案:

对不起,我没有答对这个问题。我先前的回答完全错了

因此,这里的问题是您正在使用始终相同的名称
ApplicationLogger
实例化记录器(使用
LoggerFactory
)。 此记录器无法找到
AppLog
对象的调用类,因为没有对它的引用。正如您所说的,您可以在每次调用中插入记录器名称,但这将很难维护

您可以尝试包装
记录器

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));
    }
    ...
}
在每个类中,不要使用
日志工厂
,而是使用您自己的类

private static final AppLogger APP_LOGGER = AppLogger.getLogger(CallingClass.class)
然后像这样记录

APP_LOGGER.info("message");

然后在您的模式布局中使用%c(而不是%c),它应该可以按预期工作

这不能解决我的问题。这只会从右到左限制要在包值中输出的组件。我的问题是,我总是得到Utils.AppLog,我想得到com.project.domain.Class1、com.project.dao.PersonDao等等。我更新了我的答案,因为它没有第一次得到问题。是的,我认为这样做会奏效。但也有一个小缺点。我总是使用相同的名称“ApplicationLogger”实例化记录器,因为这是我在log4j.properties中定义的一个特定记录器,用于记录到一个单独的文件。如果我将CallingClass.class传递给记录器,它将不会记录到我想要的文件,对吗?我将用有关log4j config的信息更新主要帖子。如果您不能更改记录器的名称(%c),也不能更改类的名称(%c),因为您希望有一个单独的类记录,那么现在就可以执行您想要的操作了。为什么不在所有使用logger的类中调用LogUtils呢?我将使用您的解决方案。只要一点零钱。我将把这个类传递给我的日志记录程序,它仍将由“ApplicationLogger”参数实例化。这样,我的日志包装器中就有了invoker类,可以设置调用方类的全名。我无法更改记录器的名称,因为我有多个日志文件。它们中的每一个都不能显示来自其他人的信息。。。