代码之家  ›  专栏  ›  技术社区  ›  Carmageddon

log4j2jsonlayout打印出类、方法和行以及@timestamp覆盖

  •  0
  • Carmageddon  · 技术社区  · 6 年前

    以下是我们成功开始工作的基本情况,在没有问题的情况下发布到Kibana:

            <Kafka name="KafkaAppender" topic="topic1">
            <JsonLayout compact="true">
                <KeyValuePair key="service" value="some_app_tag"/>
                <KeyValuePair key="@timestamp" value="${date:yyyy-MM-dd HH:mm:ss.SSS}"/>
                <KeyValuePair key="host_name" value="${hostName}"/>
                <KeyValuePair key="unique_id" value="$${map:name:-NA}"/>
        </JsonLayout>
            <Property name="bootstrap.servers">kafka1.com:9092,kafka2.com:9092,kafka3.com:9092</Property>
        </Kafka>
    

    JsonLayout 因此,它可以通过elasticSearch进行索引,因此可以在Kibana中作为字段进行搜索。

    我们尝试了这3个字段的各种语法组合/变体,例如 %c{2} , %M %L 对于行-它们都以我们试图输入的变量的形式打印出来。

    在控制台Appender中,它们使用: <pattern>%23.23d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] [$${map:name:-NA}] %c{1}.%M(%F:%L): %highlight{%m%n%throwable}</pattern>

    "$${map:name:-NA}" 是我们添加的,用于添加唯一的错误ID,可以根据用户收到的错误消息进行搜索,它由以下内容设置:

        StringMapMessage mapMsg = new StringMapMessage();
        mapMsg.put("name", "arun");
        LOGGER.fatal(mapMsg);
    

    我们唯一的问题是

    1. 在JSON中输出类、行和方法以进行Kafka输入

    2. 我们到目前为止还没能推翻基巴纳的计划 @timestamp 字段,以便它包含由log4j生成的时间戳,以便我们可以可靠地按生成日志的时间/日期排序(否则,如果它们是随机顺序出现的,则会造成混淆) @ 签名,Kibana添加了一个标签 _timestampparsefailure @时间戳 具有 _@timestamp

    谁能给点建议吗?我们到处找了,到目前为止还没有找到任何接近的东西。

    1 回复  |  直到 6 年前
        1
  •  1
  •   azzurroverde    5 年前

    将“locationInfo=”true“”添加到Log4j2配置文件中的JSON属性:

    <JsonLayout complete="false" locationInfo="true" properties="true" propertiesAsList="true" eventEol="true">
    
        2
  •  0
  •   Carmageddon    6 年前

    我们还没有找到办法 JsonLayout 输出类、行和方法,我们采用的解决方法是实现我们自己的布局,基本上创建一个新的自定义布局插件,因为它基本上是JsonLayout类的副本,并添加了对模式的支持:

    @Plugin(name = "CustomJsonLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
    public final class CustomJsonLayout extends AbstractJacksonLayout {
    

    在其构造函数中添加了参数:

    final boolean stacktraceAsString,
    final boolean includeNullDelimiter,
    final KeyValuePair[] additionalFields,
    final boolean objectMessageAsJsonObject
    

    然后当然把它们加到 super

    toSerializable(final LogEvent event, final Writer writer) 方法和添加私有方法 customFunctionToApplyPatternConversion 看起来像是:

    Object wrappedEvent = wrapLogEvent(convertMutableToLog4jEvent(event));
    if (wrappedEvent instanceof LogEventWithAdditionalFields) {
        LogEventWithAdditionalFields eventWithAdditionalFields = (LogEventWithAdditionalFields) wrappedEvent;
        eventWithAdditionalFields = customFunctionToApplyPatternConversion(event, eventWithAdditionalFields);
    
        wrappedEvent = eventWithAdditionalFields;
    }
    objectWriter.writeValue(writer, wrappedEvent);
    

    大部分事情都是在办公室里完成的 方法,但我不能张贴,因为我没有授权。

    这是如何添加对检测模式的支持并用值替换它们的总体思路。 如果查看JsonLayout类和PatternLayout类的完整代码,您可以更好地理解这一点—这实际上是将它们合并在一起,然后在log4j2.xml中指定CustomJsonLayout,而不是默认的。