在log4j json布局中添加自定义字段,破坏了spring日志结构。

问题描述 投票:0回答:1

我有一个Spring Boot (2.2.6)应用程序,它使用Log4j2(与Slf4j一起)。Log4j 被配置为使用 json 布局,最终我想在 Datadog 中摄取日志。为此,"serviceName "作为json中的一个字段非常重要。

现在根据log4j文档 (https:/logging.apache.orglog4j2.xmanuallayouts.html#JSONLayout。)可以添加一个带有'KeyValuePair'标签的自定义字段,这样就可以了。不幸的是,这打破了弹簧日志的正常结构。

Log4j2.xml配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <!-- Write logs to stdout, JSON, one line per log event -->
        <Console name="Console" target="SYSTEM_OUT">
            <JSONLayout compact="true" eventEol="true" includeStacktrace="true" locationInfo="true"
                        stacktraceAsString="true" properties="true">
      <KeyValuePair key="serviceName" value="$${env:APPLICATION_NAME:-local}-sidecar"/> <!-- fine w/o this line -->
</JSONLayout>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="my.service" level="debug" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="org.apache" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

日志 wo 自定义字段:

{
  "thread": "main",
  "level": "INFO",
  "loggerName": "com.nginxtrafficsidecar.ApplicationKt",
  "message": "Starting ApplicationKt on xxx with PID 17300 (C:\\Users\\Felix\\Documents\\code\\nginx-traffic-sidecar\\build\\classes\\kotlin\\main started by Felix in C:\\Users\\Felix\\Documents\\code\\nginx-traffic-sidecar)",
  "endOfBatch": false,
  "loggerFqcn": "org.apache.commons.logging.LogAdapter$Log4jLog",
  "threadId": 1,
  "instant": {
    "epochSecond": 1587975181,
    "nanoOfSecond": 331370300
  },
  "source": {
    "class": "org.springframework.boot.StartupInfoLogger",
    "method": "logStarting",
    "file": "StartupInfoLogger.java",
    "line": 55,
    "classLoaderName": "app"
  },
  "contextMap": {},
  "threadPriority": 5
}

日志 w 自定义字段

{
  "logEvent": "Starting ApplicationKt on xxx with PID 9732 (C:\\Users\\Felix\\Documents\\code\\nginx-traffic-sidecar\\build\\classes\\kotlin\\main started by Felix in C:\\Users\\Felix\\Documents\\code\\nginx-traffic-sidecar)",
  "serviceName": "local-sidecar"
}

Spring docu提到这可能会对logback产生作用,但不会对log4j产生作用 (https:/docs.spring.iospring-bootdocscurrentreferencehtmlspring-boot-features.html#boot-features-custom-log-configuration。,章末))

我已经搜索过了,但找不到任何有用的东西。有什么办法可以让我在保留所有来自Spring的字段的同时,在json日志中添加一个自定义字段?

谢谢,Felix

json spring logging log4j
1个回答
0
投票
  1. 下载 "服务名称"。杰克逊注释 并将其导入,因为 JsonLayout 使用 Jackson Annotations 内部代码。
    • 在我的例子中,下载并导入这些
jackson-annotations-2.10.3.jar
jackson-core-2.10.3.jar
jackson-databind-2.10.3.jar
  1. 增加 <JsonLayout>...</JsonLayout> 在你的配置中(在我的例子中是log4j2.xml),像下面这样。
<JsonLayout>
  <KeyValuePair key="testKey" value="testValue"/>
</JsonLayout>

替换 keyvalue 到你想使用的东西。在我的例子中 key 是 "testKey "和 value 是 "测试值"

  1. 运行并检查你的日志!它是我的全部示例代码和xml配置信息。

它是我的完整的示例代码和xml配置信息.代码。

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;

public class LogTest{
    private static final Logger logger = LogManager.getLogger(LogTest.class.getName());


    public static void main(String[] args) {
        ThreadContext.put("logFileName", "testFile1" );
        logger.info("log printed! - testFile1");

        ThreadContext.put("logFileName", "testFile2" );
        logger.info("log printed! - testFile2");

        ThreadContext.remove("logFileName");
    }

}

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Routing name="RoutingAppender">
            <Routes pattern="${ctx:logFileName}">
                <Route>
                    <RollingFile name="Rolling-${ctx:logFileName}"
                                 fileName="./logs/${ctx:logFileName}.log"
                                 filePattern="./logs/${ctx:logFileName}.%i.log.gz">
                        <JsonLayout>
                            <KeyValuePair key="testKey" value="testValue"/>
                        </JsonLayout>
                        <SizeBasedTriggeringPolicy size="512" />
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="all">
            <AppenderRef ref="RoutingAppender" />
        </Root>
    </Loggers>
</Configuration>

产出

{
  "instant" : {
    "epochSecond" : 1588590944,
    "nanoOfSecond" : 469000000
  },
  "thread" : "main",
  "level" : "INFO",
  "loggerName" : "com.test.LogTest",
  "message" : "log printed! - testFile2",
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "threadId" : 1,
  "threadPriority" : 5,
  "testKey" : "testValue"
}

© www.soinside.com 2019 - 2024. All rights reserved.