Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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_Log4j2 - Fatal编程技术网

Java 自定义log4j日志管理器,以便在所有日志中包含前缀

Java 自定义log4j日志管理器,以便在所有日志中包含前缀,java,logging,log4j2,Java,Logging,Log4j2,在我的项目中,我有各种不同的模块,对于所有日志记录,它们在消息中配置一个前缀以进行隔离。比如说 私有静态最终记录器log=LogManager.getLogger(MethodHandles.lookup().lookupClass()) 项目1所有日志: log.info("{} my message my args{}", Project1.KEY, args); log.info("{} my message my args{}", Project2.KEY, args); 项目2所有

在我的项目中,我有各种不同的模块,对于所有日志记录,它们在消息中配置一个前缀以进行隔离。比如说

私有静态最终记录器log=LogManager.getLogger(MethodHandles.lookup().lookupClass())

项目1所有日志:

log.info("{} my message my args{}", Project1.KEY, args);
log.info("{} my message my args{}", Project2.KEY, args);
项目2所有日志:

log.info("{} my message my args{}", Project1.KEY, args);
log.info("{} my message my args{}", Project2.KEY, args);
每个模块如何配置
LogManager
,以使密钥前缀自动附加到每条消息中,而不是手动提供密钥

我通过扩展
AbstractMessageFactory
解决了这个问题,这种方法需要在每个模块中重复大量相同的代码

public class CustomLogManager extends LogManager {

    private static final class CustomMessageFactory extends AbstractMessageFactory {

        public static final CustomMessageFactory INSTANCE = new CustomMessageFactory();

        private String messageWithPrefix(String message) {
            return prefix + SEPARATOR + message;
        }

        @Override
        public Message newMessage(String message, Object... params) {
            return new ParameterizedMessage(messageWithPrefix(message), params);
        }

        @Override
        public Message newMessage(final String message, final Object p0) {
            return new ParameterizedMessage(messageWithPrefix(message), p0);
        }

        ... other overloads ...

    }

    private static final Prefix prefix = Prefix.one;

    public static Logger getLogger(final Class<?> clazz) {
        return getLogger(clazz, CustomMessageFactory.INSTANCE);
    }

}
公共类CustomLogManager扩展LogManager{
私有静态最终类CustomMessageFactory扩展了AbstractMessageFactory{
公共静态最终CustomMessageFactory实例=新建CustomMessageFactory();
私有字符串消息WithPrefix(字符串消息){
返回前缀+分隔符+消息;
}
@凌驾
公共消息newMessage(字符串消息、对象…参数){
返回新的参数化消息(messageWithPrefix(message),params);
}
@凌驾
公共消息newMessage(最终字符串消息,最终对象p0){
返回新的参数化消息(messageWithPrefix(message),p0);
}
…其他重载。。。
}
私有静态最终前缀前缀=Prefix.one;
公共静态记录器getLogger(最终类clazz){
返回getLogger(clazz,CustomMessageFactory.INSTANCE);
}
}

定制
ParameterizedMessageFactory
以仅包含前缀字符串是否可行?

根据您的情况,我将创建一个界面,其中包含您正在查找的信息以及一个键—可能是每个jar特有的包名(我希望您不要在jar之间混合包名)。然后,我将在每个jar中创建该接口的实例,并按照java.util.ServiceLoader将其注册为服务


然后,我将创建一个Log4j2查找,它使用ServiceLoader查找所有实例,并在初始化期间将它们添加到映射中。然后,我会在我的Log4j配置中使用该查找来使用LogEvent中的Logger查找适当的值(假设Logger遵循使用类名作为名称的惯例)。

您的问题的挑战是“什么是模块”?它是一个简单的jar文件,与所有其他jar都在同一个类加载器中吗?它是Java平台模块系统中的Java模块吗?它是某种其他插件吗?Log4j有几种方法可以做到这一点,但如果不了解如何确定哪个模块处于“活动”状态,则很难回答。@rgoers它们在gradle设置中是不同的项目。看见每个项目都在定义自己的
build.gradle
Ok。因此,我假设这与maven多模块项目相同,并且您正在生成多个JAR。是的,正确。所有这些都是作为单个jar生成的,我认为我不能定制log4j2.xml,因为它是在公共框架中构建的。