【问题标题】:How do I add a prefix to log4j messages (at the object level)如何为 log4j 消息添加前缀(在对象级别)
【发布时间】:2013-05-23 20:10:46
【问题描述】:

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

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

感谢您的帮助

【问题讨论】:

  • 如果log4j2支持MDC你可以放在那里。
  • 好建议。它确实支持MDC
  • 感谢它与 log4j2 中的 ThreadContext 一起使用
  • 一个键可以放多个值吗?
  • 最后我创建了一个实现 MessageFactory 的类 LogMessage 并用前缀连接消息。在我创建像这样private Logger logger = LogManager.getLogger("MyClass", new LogMessage(prefix)); 这样的记录器之后,它就可以工作了

标签: java log4j log4j2


【解决方案1】:

使用 MDC 实现这一目标

在你的构造函数中放

 MDC.put("prefix", yourvalue);

在你的 XML 中像这样在模式中使用它

      %X{prefix}

【讨论】:

  • 不同的线程可以为同一个键放置不同的值。该映射是线程本地的,因此每个线程都有一个单独的副本。
【解决方案2】:

基于比尔·克拉斯的回答:

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");
    }
}

【讨论】:

  • 或者您可以扩展 Logger 并覆盖日志记录方法
  • 我以前试过这个...它总是会打印与日志消息来源完全相同的file:line。它将始终为 LogWrapper:26,因为您的 log4j 记录器调用位于您的 LogWrapper 类中的第 26 行(例如)。您需要扩展 log4j 记录器,但这仍然不是微不足道的(至少,它不在 log4j 1.2 上)。
  • 据我了解,问题要求在所有消息之前简单地加上一个数字前缀...
  • 我只是指出,虽然回答了这个问题,但它不是很实用,因为您正在丢失有价值的信息。除非你不在乎你的日志来自哪里,在这种情况下,我想知道你为什么要使用日志框架进行日志记录,而不是简单地将所需的信息打印到文件中。
【解决方案3】:

这是一个简单的解决方案:您可以用一种方法包装字符串,向它添加前缀并将连接的字符串返回给error方法。

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"));

    }

}

优点:

  • 简单
  • 您可以在一个类/方法中记录带前缀和不带前缀的消息
  • 您不必将 %X{prefix} 之类的内容永久添加到 log4j2 配置中

缺点:

  • 如果你想添加前缀,你总是必须使用包装方法

【讨论】:

  • 而如果你想在你创建的每个类中使用这个包装方法,你可以使用静态导入而不是在每个类中声明方法
【解决方案4】:

一种解决方案是包装类。

public class YourLogger
{
    private Logger log;

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

【讨论】:

  • 我试试这个,但是调用类和行号都丢失了。
  • @Boubee 你的变量包含受影响的代码行号。是吗?
  • 不,我的变量是序列号
  • 查看我在 DiaryLea 的回答上写的评论。
【解决方案5】:

试试这个

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

【讨论】:

  • 有了这个,你不是必须在你创建的每个类中为每个日志级别创建一个方法吗?
  • 是的,我知道不需要创建单独的方法。为了 OP 的理解,我写了这个。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2022-07-06
  • 2011-10-14
  • 2018-11-01
  • 2016-02-06
相关资源
最近更新 更多