将任意对象传递到Log4j中的ThreadContext.put()



我想将任意对象传递给ThreadContext.put()方法,如下所示:

MyObject originalMessage = new MyObject(...);
ThreadContext.put("originalMessage", originalMessage);

但该方法只允许String作为其第二个参数:此处为docs。

有没有办法把log4j中的任意对象放在log4j的MDC中?还是其他选择?我想要的是允许log.error()的进一步执行自动记录originalMessage,而不需要将其作为参数到处传递。

此外,我自己不能调用toString(),因为我会急切地评估该方法(在这个对象中这个方法相当重(,所以我希望它的调用被延迟到需要的时候,就像将任意对象传递给log.debug("{}", someObject)一样。

我终于在这里找到了一个(破解(解决方案。

而不是这个(它不编译(:

ThreadContext.put("originalMessage", originalMessage);

我可以做:

final var threadContextMap = (ObjectThreadContextMap) ThreadContext.getThreadContextMap();
threadContextMap.putValue("originalMessage", originalMessage);

只要您添加以下JVM选项,它就会起作用:

-Dlog4j2.threadContextMap=org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap

现在,这看起来很糟糕,因为getThreadContextMap((方法应该返回内部映射的只读视图:

返回用于存储线程上下文键值对的内部数据结构的只读视图。。。

所以这个解决方案是强制转换只读映射,并且知道实现不是只读的,就修改它。。。不是最透明的解决方案,但它是有效的。

最新更新