所以我们有一个应用程序,它将所有日志(通过Kafka服务器)发送到Kibana服务器。
以下是我们设法工作的基础,没有任何问题地发布到了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个字段尝试了各种语法组合/变体,例如Line的%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,该错误ID的设置方式如下:
StringMapMessage mapMsg = new StringMapMessage();
mapMsg.put("name", "arun");
LOGGER.fatal(mapMsg);
这可行,我们唯一的问题是
在JSON中为Kafka输入输出类,行和方法
到目前为止,我们无法覆盖Kibana的@timestamp
字段,因此它包含由log4j生成的时间戳,因此我们可以按生成日志的时间/日期可靠地进行排序(否则,它们会如果它们按随机顺序出现,将会造成混乱)-当我们添加@
符号时,Kibana会添加诸如_timestampparsefailure
之类的标签,并以@timestamp
显示提交的_@timestamp
,而不是使用它来覆盖它生成的时间戳。
有人可以建议吗?我们已经进行了广泛的搜索,到目前为止还没有找到任何东西。
谢谢。
答案 0 :(得分:0)
我们还没有找到一种制作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);
大多数内容都是在customFunctionToApplyPatternConversion
方法内部完成的,但由于未经授权,我无法发布。
这是如何增加对检测模式的支持并将其替换为值的一般思路。 如果您查看JsonLayout类和PatternLayout类的完整代码,则可以更好地理解这一点-本质上是将它们合并在一起,然后在log4j2.xml中指定CustomJsonLayout而不是默认的。
答案 1 :(得分:0)
Add "locationInfo="true" " to the JSON properties in the Log4j2 config file: For Example:
<JsonLayout complete="false" locationInfo="true" properties="true" propertiesAsList="true" eventEol="true">