Java 如何向log4j消息添加前缀(在对象级别)

Java 如何向log4j消息添加前缀(在对象级别),java,log4j,log4j2,Java,Log4j,Log4j2,我使用log4j2,我想为我的所有消息添加一个前缀。此前缀传递给构造函数参数,它取决于类的实例。因此,我们处于对象级别(而不是类或线程) 例如,我有一个A类实例化为newa(152),所以当我在这个类上使用log.error(“message”)时,152:就写在消息之前。对于新A(155),将显示155: 感谢您的帮助一个解决方案是包装器类 public class YourLogger { private Logger log; public void error(int

我使用log4j2,我想为我的所有消息添加一个前缀。此前缀传递给构造函数参数,它取决于类的实例。因此,我们处于对象级别(而不是类或线程)

例如,我有一个
A
类实例化为
newa(152)
,所以当我在这个类上使用
log.error(“message”)
时,
152:
就写在消息之前。对于
新A(155)
,将显示
155:


感谢您的帮助

一个解决方案是包装器类

public class YourLogger
{
    private Logger log;

    public void error(int value, String msg)
    {
        log.error(String.valueOf(value) + ": " + msg);
    }
}

使用MDC来实现这一点

在你的构造器里

 MDC.put("prefix", yourvalue);
在XML中,在模式中使用它

      %X{prefix}
试试这个

public void writeError(String msg,int intValue) {
logger.error(intValue+" "+msg);
}

根据比尔·克莱尔的回答:

public class LogWrapper
{
    private Logger log;
    private String prefix;

    public LogWrapper(Logger log, String prefix) {
        this.log = log;
        this.prefix = prefix;
    }

    public void error(String msg)
    {
        log.error(prefix + ": " + msg);
    }
}
然后在类中设置为实例变量

public class MyClass {
    private LogWrapper log;

    public MyClass(int prefix) {
        log = new LogWrapper(Logger.getLogger(this.getClass()), String.valueOf(prefix));

        // then log away
        log.error("Test");
    }
}

这里有一个简单的解决方案:您可以使用方法包装字符串,该方法将前缀添加到字符串中,并将连接的字符串返回到
错误
方法

public class A {
    private static final Logger LOG = LogManager.getLogger();

    final int index;

    public A(int index) {
        this.index = index;
    }

    public static void f(String message) {
        return String.valueOf(index) + ": ";
    }

    public void method() {

        // ...

        LOG.error(f("message"));

    }

}
优点:

  • 简单的
  • 您可以在一个类/方法中记录带有或不带前缀的消息
  • 您不必向log4j2配置中永久添加类似
    %X{prefix}
    的内容
缺点:

  • 如果要添加前缀,则必须始终使用包装器方法


如果log4j2支持MDC,您可以将其放在那里。建议不错。它确实支持MDCThanks它在Log4j2中与ThreadContext一起工作是否可以为一个键放置多个值?最后,我创建了一个类LogMessage,它实现了MessageFactory ans I将消息与前缀连接起来。在我像这样创建记录器之后,
private logger logger=LogManager.getLogger(“MyClass”,新的LogMessage(前缀))和它的工作原理我尝试了这个,但是调用类和行号丢失了。@Boubee我想你的变量包含有效的代码行号。是吗?不是,我的变量是一个序列号请看我在DiaryLea的答案上写的注释。或者你可以扩展
Logger
并覆盖日志记录方法我以前尝试过这个。。。它将始终打印与日志消息来源完全相同的
文件:行
。它总是
LogWrapper:26
,因为log4j记录器调用位于
LogWrapper
类的第26行(例如)。您需要扩展log4j日志,但这仍然不是一件小事(至少,它不在log4j 1.2上)。据我所知,问题是在所有消息之前简单地加上一个数字前缀……我只是指出,尽管回答了这个问题,但这并不实用,因为您正在丢失有价值的信息。除非您不关心日志来自何处,否则我想知道为什么您使用日志框架进行日志记录,而不是简单地将所需信息打印到文件中。这样,您不必为每个日志记录级别创建一个方法吗,在你创建的每个类中?是的,我知道不需要创建seprate方法。为了OP的理解,我写了这个。不同的线程可以为同一个键设置不同的值。映射是threadlocal的,因此每个线程都有一个单独的副本。如果您想在创建的每个类中使用此包装方法,可以使用静态导入,而不是在每个类中声明该方法