Log4j2 的JsonTemplateLayout - 将日志消息字段作为JSON。

4

我有这个 log4j2.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
    <Console name="JsonAppender" target="SYSTEM_OUT">
        <JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json" />
    </Console>
</Appenders>
<Loggers>
    <Logger name="JsonLogger" level="INFO" additivity="false">
        <AppenderRef ref="JsonAppender"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="JsonAppender"/>
    </Root>
</Loggers>
</Configuration>

在我的代码中,我有一个类似的日志记录语句:
HashMap logMap = new HashMap<>();
        logMap.put("appId", "123456789");
        logMap.put("action", "Received request");

        logger.info(new ObjectMessage(logMap));

在我的日志中,我得到了以下信息:
 {
        "@timestamp": "2022-02-02T10:52:56.100Z",
        "ecs.version": "1.2.0",
        "log.level": "INFO",
        "message": "{appId=123456789, action=Received request}",
        "process.thread.name": "main",
        "log.logger": "org.xxxx.App" 
}

好的,但我希望 message 以 json 格式呈现,所以想要:

"message": {
              "appId": "123456789", 
              "action": "Received request"
}

我知道使用 JsonLayout 时必须指定 objectMessageAsJsonObject="true",但是在使用 JsonTemplateLayout 时可能会更加微妙。

TIA.

2个回答

3
阅读JSON模板布局文档后,您可以通过利用eventTemplateAdditionalField参数修改事件模板字段。
看起来有几种方法可以解决这个问题,但我选择的选项是修改log4j2.xml文件:
<Appenders>
        <Console name="JsonAppender" target="SYSTEM_OUT">
            <JsonTemplateLayout eventTemplateUri="classpath:LambdaEcsLayout.json">
                <EventTemplateAdditionalField
                        key="message"
                        format="JSON"
                        value='{"$resolver": "message", "field": "name"}'/>/>
            </JsonTemplateLayout>

        </Console>
    </Appenders>

当记录日志时,可以像这样:

var logMap = new HashMap<>();
        logMap.put("id", "123456789");
        logMap.put("action", "Received request");
        var om = new ObjectMessage(logMap);

        log.info(om);

处理后者可能有更简洁的方法,例如某种包装器等-但您已经了解了这个想法。


很好。对我有用。 - undefined
嗯,经过审查,这对我来说行不通。它对某些任意对象不起作用,例如我得到"message":{"x":{"a":"b"},"p":"com.xyz.Person@3132fc"} x是一个映射,没问题。p是一个bean,是错误的,但使用jsonLayout却可以正常工作。为什么这一切都这么难?太荒谬了。 - undefined

0

我成功地使用了@Hurricane的方法,但在试图简化它时,我发现您可以省略<EventTemplateAdditionalField>元素并添加

"message": {
    "$resolver": "message",
    "stringified": false
}

而是返回到模板布局中。您还可以省略'stringified'属性,因为它的默认值为'false'。OP没有包含布局,但我怀疑他将'stringified'设置为'true'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接