【问题标题】:log4j PatternLayout for class level variables类级别变量的 log4j PatternLayout
【发布时间】:2015-10-01 22:29:21
【问题描述】:

我的类在实例化时有一个与之关联的 Id。我希望能够记录类似于 MDC/PatternLayout 的对象级别信息。不确定如果我把它放在 MDC 中这是否可行,因为我不知道一个线程将执行一个对象的一种方法。有没有办法在 log4j 中做到这一点?

2015-10-01 12:52:03,117 [priority="INFO", thread="ForkJoinPool-1-worker-7", myObjectId="3838901231"] com.company.projectA.classA - initialization started

在上面的示例中,myObjectId 是针对应该打印的每个对象,而无需将其写入 logger.info() 语句中。

【问题讨论】:

  • 请澄清:您希望何时记录该 ID?只有当对象被实例化时?对于与该对象关联的所有日志语句?您何时想记录该 ID?
  • Id 在 init() 被调用后可用,所以在那之后我想在所有日志记录语句中打印 id。如果 id 不可用,则可以打印空字符串。
  • 编辑:我只想在类中编写的那些语句中记录 Id。课堂外的任何陈述都不应打印。这几乎就像用类名初始化一个记录器,这样类中的所有语句都将打印该类名,但如果它可用,也会连同 id 一起打印。获得 MDC/PatternLayout 的灵活性会很好。在调用 init() 后 ID 可用,因此在那之后我想在所有日志记录语句中打印 id。如果 id 不可用,则可以打印空字符串。

标签: logging log4j slf4j logback log4j2


【解决方案1】:

通常将记录器最有效地声明为静态字段,如下所示:

package com.mycomp.xyz;
class MyClass {
    private static Logger logger = LogManager.getLogger(MyClass.class);
    ....

包含%c(记录器名称)的模式布局将在日志文件中显示记录器名称(在本例中为com.mycomp.xyz.MyClass)。

一个想法是做一些不同的事情,并在记录器名称中包含 ID。

所以延迟创建记录器,直到您知道 ID,然后将其创建为 LogManager.getLogger(getClass().getName() + "." + id)。请注意,记录器不能再是静态字段,因为会有多个实例:每个 ID 一个。

然后%c 模式布局转换器将包含该记录器生成的所有日志语句的记录器名称和 ID。

【讨论】:

  • 实际上,我已经在这样做了,只是在前面加上了 id [myObjectId="3838901231"] com.company.projectA.classA。我仍在寻找更灵活的方法。
  • 你想解决什么问题?你不喜欢哪个方面?
  • 我必须对密钥“myObjectId”进行硬编码。我可以将它放在属性文件中,但理想情况下它应该是 log4j.xml 配置文件的一部分,以便我可以在那里声明所有格式。此外,我必须在获得 Id 后再次初始化记录器。
  • Hm... 还有其他方法可以做到这一点,您可以使用自定义查找插件,也许可以代替字符串记录包含 ID 的自定义消息对象,以便查找可以提取 ID,但在这一点你必须为这种灵活性做很多工作,我不确定这是否值得。
猜你喜欢
  • 2011-12-10
  • 2011-01-23
  • 2013-03-06
  • 2011-06-03
  • 1970-01-01
  • 2022-11-10
  • 2018-10-01
  • 2012-10-03
  • 1970-01-01
相关资源
最近更新 更多