当我在intellij Idea中运行main方法时,我的项目中有log4j2,打印日志是正确的。
当我使用 maven-shade-plugin 包项目到 jar 文件,并将 jar 作为独立应用程序运行时,它显示错误:
java -cp package.jar com.xxx.TestMain
控制台输出
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
pom.xml 配置。 log4j2.version = 2.10.0,spring boot版本是1.5.9.RELEASE
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<sourceDirectory>src/main/java</sourceDirectory>
</build>
log4j2.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" monitorInterval="30" shutdownHook="disable">
<properties>
<property name="LOG_HOME">/data1/logs</property>
<property name="JOB_NAME">noname</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss} [%t] %level [%logger{36}][%file:%line] %msg%n%throwable"/>
</Console>
<RollingRandomAccessFile name="DetailFile"
fileName="${sys:LOG_HOME}/${sys:JOB_NAME}/detail.log" bufferedIO="false"
filePattern="${sys:LOG_HOME}/${sys:JOB_NAME}/detail.%d{yyyy-MM-dd}-%i.log">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss} [%t] %level [%file:%line] %msg%n%throwable"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="500 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="error"
fileName="${sys:LOG_HOME}/${sys:JOB_NAME}/error.log" bufferedIO="true"
filePattern="${sys:LOG_HOME}/${sys:JOB_NAME}/error.%d{yyyy-MM-dd}.log">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss} [%t] %level [%logger{36}:%line] %msg%n%throwable"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="DetailFile"/>
<AppenderRef level="error" ref="error"/>
</Root>
</Loggers>
</Configuration>
如果依赖项包含 log4j2 插件,则 jar 中会包含一个
Log4j2Plugins.dat
缓存文件。当使用 Maven 阴影插件将多个 jar 与一个 Log4j2Plugins.dat
文件合并时,只有一个能够幸存。如果没有插件定义,启动时会显示错误。 Log4j2问题
解决此问题的一个解决方案是从阴影 jar 中排除
Log4j2Plugins.dat
缓存文件,以便 Log4j 在启动时扫描插件。为此,请在 pom 中的 maven-shade-plugin
配置中添加一个过滤器:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>**/Log4j2Plugins.dat</exclude>
</excludes>
</filter>
</filters>
</configuration>
<!-- ... -->
</plugin>
另一个解决方案是使用特定于 log4j 版本的转换插件合并缓存文件。
如果您使用 Gradle 和 ShadowJar 4+:
shadowJar {
transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer)
}
Gradle Kotlin DSL:
shadowJar {
transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer::class.java)
}
不幸的是,我无法回复 Shashank Kapoor 的回答,因为他正确地指出排除
Log4j2Plugins.dat
文件可以解决问题。这在使用 gradle 时对我有用:
shadowJar {
exclude "**/Log4j2Plugins.dat"
}
我以前见过这个错误,当时人们在类路径上有多个版本的 Log4j2。
对于我们这些从类路径中删除旧 Logj42 以修复 Log4Shell (CVE-2021-44228) 漏洞的人来说,升级后使用 uber jar 时可能会发现此问题。
如果您从 Maven 或 Gradle 构建 uber jar,请分别使用以下插件之一:
如果您通过其他方式构建它们,请参阅此答案:https://stackoverflow.com/a/70497498/1174024。但基本上你必须像此类一样正确处理 Log4j2 插件缓存文件:
在构建新的 uber jar 时正确处理
Log4j2Plugins.dat
文件。
在我们的项目中,创建
TestAppender
类后出现了这样的问题。
@Plugin(name = "TestAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
public class TestAppender extends AbstractAppender {
...
其设置覆盖了
Log4j2Plugins.dat
文件中的记录器设置。
然后我们将其移动到一个单独的模块,并开始以类似的方式将其附加到项目中(请注意范围):
<dependency>
<groupId>info.project</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
这个链接对我有用。着色 log4j 时出现问题
<filter>
<artifact>log4j:log4j</artifact>
<includes>
<include>org/apache/log4j/spi/LoggingEvent.class</include>
</includes>
</filter>
<filter>
<artifact>org.apache.logging.log4j:log4j-*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
@PowerMockIgnore( {"org.springframework.util.Log4jConfigurer","javax.script.*","javax.management.*", "org.w3c.dom.*", "org.apache.log4j.*","org.apache.logging.*","org.apache.commons.logging.*", "org.xml.sax.*", "javax.xml.*"})
将此片段添加到测试类中。不再有错误日志。
您可以排除所有
Log4j2Plugins.dat
文件,除了正确的文件,即 log4j-core
中包含的文件:
<filter>
<artifact>SOME-ARTIFACT</artifact>
<excludes>
<exclude>**/Log4j2Plugins.dat</exclude>
</excludes>
</filter>
<filter>
<artifact>SOME-ARTIFACT</artifact>
<excludes>
<exclude>**/Log4j2Plugins.dat</exclude>
</excludes>
</filter>
...
请参阅此处的答案和示例项目:https://stackoverflow.com/a/76003471/1121497
您是否尝试过在 log4j2.xml 文件中使用“Configuration”标签的“package”属性。例如,
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config"
packages="my.app.logging.converter"
name="MyConverter">
<Appenders>
...
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>