使用JSONLayout的log4j2和自定义键值

使用JSONLayout的log4j2和自定义键值,log4j2,Log4j2,我想使用Log4j2向日志中添加一个字符串键和一个整数值。 有办法吗?当我向ThreadContext添加属性时,我只能添加String:String键和值,但这无助于我在Kibana中提供需要的数字(一些图形) 谢谢, Kobi我发现默认的log4j2实现在传递带有值的自定义字段时有些问题。在我看来,当前的java日志框架并不适合编写结构化日志事件 如果你喜欢黑客,你可以查看。这是为盖尔夫写的图书馆。提供的功能之一是一个布局(ExtGelfjLayout),它支持从事件中提取自定义字段(请参见

我想使用Log4j2向日志中添加一个字符串键和一个整数值。 有办法吗?当我向ThreadContext添加属性时,我只能添加String:String键和值,但这无助于我在Kibana中提供需要的数字(一些图形)

谢谢,
Kobi

我发现默认的log4j2实现在传递带有值的自定义字段时有些问题。在我看来,当前的java日志框架并不适合编写结构化日志事件


如果你喜欢黑客,你可以查看。这是为盖尔夫写的图书馆。提供的功能之一是一个布局(ExtGelfjLayout),它支持从事件中提取自定义字段(请参见FieldExtractor)。但是为了发送这样的事件,您需要在log4j2之上编写自己的日志外观

内置的GelfLayout可能很有用

默认的ThreadContext确实只支持String:String键值。中完成的工作允许您在ThreadContext中使用其他类型:

  • 告诉Log4j使用实现ObjectThreadContextMap接口的ThreadContext映射实现。实现这一点的最简单方法是将系统属性
    log4j2.garbagefree.threadContextMap
    设置为
    true
  • 标准的ThreadContext facade只有用于字符串的方法,因此您需要创建自己的facade。以下各项应起作用:

    public class ObjectThreadContext {
      public static boolean isSupported() {
          return ThreadContext.getThreadContextMap() instanceof ObjectThreadContextMap;
      }
    
      public static Object getValue(String key) {
          return getObjectMap().getValue(key);
      }
    
      public static void putValue(String key, Object value) {
          getObjectMap().putValue(key, value);
      }
    
      private static ObjectThreadContextMap getObjectMap() {
          if (!isSupported()) { throw new UnsupportedOperationException(); }
          return (ObjectThreadContextMap) ThreadContext.getThreadContextMap();
      }
    }
    

  • 通过将另一个源的键值对注入LogEvent,可以完全避免ThreadContext。在Custom Context Data Injectors()中(简要地)提到了这一点。

    Log4j2有一个内置的GelfLayoutYes,但它不支持字符串以外的值。更不用说使用线程上下文(上下文映射)传递值是多么不直观了,我现在明白你的意思了。在ThreadContext中有一些正在进行的工作来支持其他类型:和。通过将另一个源的键值对注入LogEvent,可以完全避免ThreadContext。这在Custom Context Data Injectors()中(简要地)提到过。我想,我可以/应该包括一个示例,说明我们如何在不使用ThreadContext的情况下实现这一点。