Log4j 格式(通过 -Dlog4j.configurationFile)在某些环境中不起作用

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

我们的应用程序使用 log4j 来控制日志记录行为。它通过 log4 配置 xml 文件(下面的完整配置)的

Field
部分中的
Configuration.Appenders.RollingFile.StructuredLayout
元素指定日志行的格式。

问题:日志格式仅在我们的某些环境中使用,而在其他环境中不使用。

我们像这样将 log4j xml 配置传递给应用程序,每个环境都相同

# command in stage
java -Dlog4j.configurationFile=/opt/ais/config/log4j2.xml -jar myApp.jar

# command in production
java -Dlog4j.configurationFile=/opt/ais/config/log4j2.xml -jar myApp.jar

阶段的日志没有格式。生产中的日志具有我们期望的格式(在 xml 中指定)。

# in stage (no format, not working)
> cat /opt/ais/logs/splunk/myApp/host-0-443.log
test log message

# in prod (format, working as expected)
> cat /opt/ais/logs/splunk/myApp/host-0-443.log
timestamp="2023-05-03 07:13:15,461",level="INFO",thread="pool-2-thread-1",message="test log message",logger="MessageProcessor",appName="myApp",instanceNum="300",dataCenter="MR",partition="MR",buildVersion="1.0.0"

每台主机上都有xml文件,文件路径匹配。那么是什么导致一个环境支持日志格式,而另一个环境不支持?

完整的 log4j 配置 xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.apple.jvm.commons.logging.structured">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <StructuredLayout/>
    </Console>
    <RollingFile name="RollingFile"
                 fileName="/opt/ais/logs/splunk/${sys:ISApplicationName}/${sys:ISHostId}-${sys:ISInstanceId}-${sys:WOPort}.log"
                 filePattern="/opt/ais/logs/${sys:ISApplicationName}/${sys:ISHostId}-${sys:ISInstanceId}-${sys:WOPort}.%i.log">
      <StructuredLayout serializer="com.mycompany.jvm.commons.logging.structured.kv.KeyValueSerializer" fieldSeparator="," timeZoneId="America/Los_Angeles">
        <Field name="timestamp" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS}{America/Los_Angeles}"/>
        <Basic exclude="timestamp"/>
        <Throwable name="exception"/>
        <Field name="appName" value="${sys:ISApplicationName}"/>
        <Field name="instanceNum" value="${sys:ISInstanceId}"/>
        <Field name="dataCenter" value="${sys:ISDataCenter}"/>
        <Field name="partition" value="${sys:partition}"/>
        <Field name="buildVersion" value="${sys:build.version}"/>
      </StructuredLayout>
      <Policies>
        <SizeBasedTriggeringPolicy size="500 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="RollingFile"/>
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>
java xml logging log4j
1个回答
0
投票

问题是 StructuredLayout

com.mycompany.jvm.commons.logging.structured.kv.KeyValueSerializer
中的序列化程序在依赖图中不可用。我们的生产构建正在运行,但在最后一个生产构建和当前构建的暂存之间的某个时间,该依赖性被删除了。谁知道为什么,但这可能是因为我们“幸运”并通过传递依赖获得了依赖,但这不再是真的。

修复是向 gradle 添加运行时依赖项,以包含缺少的

KeyValueSerializer
类型。

runtimeOnly("com.mycompany.jvm.commons.commons-logging:structured-layout-log4j2:1.11.1")

注意这个依赖是我们自己的内部神器,YMMV

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