log4j2和使用JSONLayout的自定义键值

时间:2017-03-03 22:04:49

标签: log4j2

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

感谢, 科比

2 个答案:

答案 0 :(得分:1)

内置的GelfLayout可能很有用。

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

  1. 告诉Log4j使用实现ObjectThreadContextMap接口的ThreadContext映射实现。实现此目的的最简单方法是将系统属性log4j2.garbagefree.threadContextMap设置为true
  2. 标准的ThreadContext外观只有字符串的方法,因此您需要创建自己的外观。以下应该有效:

    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();
      }
    }
    
  3. 通过将来自另一个源的键值对注入LogEvent,可以完全避免ThreadContext。这是(简要)在自定义上下文数据注入器(http://logging.apache.org/log4j/2.x/manual/extending.html#Custom_ContextDataInjector)下提到的。

答案 1 :(得分:0)

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

如果您喜欢黑客,可以查看https://github.com/skorhone/gelfj-alt/tree/master/src/main/java/org/graylog2/log4j2。这是一个为gelf编写的库。提供的功能之一是布局(ExtGelfjLayout),它支持从事件中提取自定义字段(请参阅FieldExtractor)。但是......为了发送这样的事件,你需要在log4j2之上编写自己的日志记录。