Log4J2 JsonLayout 打印出 class、方法和行以及@timestamp 覆盖
Log4J2 JsonLayout printing out class, method and line and @timestamp override
所以我们有一个应用程序,我们将把它的所有日志发送到 Kibana 服务器(通过 Kafka 服务器)。
以下是我们设法开始工作的基础知识,可以毫无问题地发布到 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
中打印出 class、方法和行号,以便它可以被 elasticSearch 索引,因此可以在 Kibana 中作为一个字段进行搜索。
我们为这 3 个字段尝试了各种语法 combinations/variations,例如 Line 的 %c{2}
、%M
和 %L
- 它们都按字面意义打印为我们的变量尝试放入。
在 Console 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);
这行得通,我们唯一的问题是
输出class,JSON中Kafka输入的行和方法
到目前为止,我们无法覆盖 Kibana 的 @timestamp
字段,因此它包含 log4j 生成的时间戳,这样我们就可以可靠地按 time/date 日志排序是生成的(否则如果它们以随机顺序出现会造成混淆) - 当我们添加 @
符号时,Kibana 添加了一个标签,如 _timestampparsefailure
,并显示提交的 @timestamp
和 _@timestamp
,而不是用它来覆盖它生成的时间戳。
请问有人能指点一下吗?我们四处搜寻,到目前为止还没有找到任何接近的东西。
谢谢。
我们还没有找到使 JsonLayout
输出 class 的方法,行和方法,我们采用的解决方法是实现我们自己的布局,基本上就是创建一个新的自定义布局插件基本上是 JsonLayout class 的副本,增加了对模式的支持:
@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);
大部分内容都是在 customFunctionToApplyPatternConversion
方法中完成的,但我不能 post 因为我没有被授权。
这是关于如何添加对检测模式的支持并用值替换它们的一般思路。
如果您查看 JsonLayout classes 和 PatternLayout classes 的完整代码,您可以更好地理解这一点 - 这实际上是将它们合并在一起,然后在 log4j2.xml 中指定 CustomJsonLayout而不是默认的。
将 "locationInfo="true" " 添加到 Log4j2 配置文件中的 JSON 属性:
例如:
<JsonLayout complete="false" locationInfo="true" properties="true" propertiesAsList="true" eventEol="true">
所以我们有一个应用程序,我们将把它的所有日志发送到 Kibana 服务器(通过 Kafka 服务器)。
以下是我们设法开始工作的基础知识,可以毫无问题地发布到 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
中打印出 class、方法和行号,以便它可以被 elasticSearch 索引,因此可以在 Kibana 中作为一个字段进行搜索。
我们为这 3 个字段尝试了各种语法 combinations/variations,例如 Line 的 %c{2}
、%M
和 %L
- 它们都按字面意义打印为我们的变量尝试放入。
在 Console 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);
这行得通,我们唯一的问题是
输出class,JSON中Kafka输入的行和方法
到目前为止,我们无法覆盖 Kibana 的
@timestamp
字段,因此它包含 log4j 生成的时间戳,这样我们就可以可靠地按 time/date 日志排序是生成的(否则如果它们以随机顺序出现会造成混淆) - 当我们添加@
符号时,Kibana 添加了一个标签,如_timestampparsefailure
,并显示提交的@timestamp
和_@timestamp
,而不是用它来覆盖它生成的时间戳。
请问有人能指点一下吗?我们四处搜寻,到目前为止还没有找到任何接近的东西。
谢谢。
我们还没有找到使 JsonLayout
输出 class 的方法,行和方法,我们采用的解决方法是实现我们自己的布局,基本上就是创建一个新的自定义布局插件基本上是 JsonLayout class 的副本,增加了对模式的支持:
@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);
大部分内容都是在 customFunctionToApplyPatternConversion
方法中完成的,但我不能 post 因为我没有被授权。
这是关于如何添加对检测模式的支持并用值替换它们的一般思路。 如果您查看 JsonLayout classes 和 PatternLayout classes 的完整代码,您可以更好地理解这一点 - 这实际上是将它们合并在一起,然后在 log4j2.xml 中指定 CustomJsonLayout而不是默认的。
将 "locationInfo="true" " 添加到 Log4j2 配置文件中的 JSON 属性: 例如:
<JsonLayout complete="false" locationInfo="true" properties="true" propertiesAsList="true" eventEol="true">