我正在开发一个利用log4j2日志记录的项目。 在intellij开发时,一切正常,日志记录按预期完成。 log4j2.xml通过intellij设置在启动时传递给jvm的java属性链接。 但是一旦我尝试运行一个独立的gradle build fat-jar,我遇到了以下问题:
java -Dlog4j.debug=true -Dlog4j.configurationFile=/home/aaa/log4j2.xml -jar /home/aaa/myjar-SNAPSHOT.jar
例外:
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 No log4j2 configuration file found. Using default configuration: logging only errors to the console.
我甚至不知道那些[thread]来自哪里,因为即使在我的log4j2中使用基本最简单的配置我也会得到同样的错误:
<?xml version="1.0" encoding="UTF-8" ?><Configuration status="WARN" monitorInterval="86400">
<Appenders>
<Console name="console-log" target="SYSTEM_OUT">
<PatternLayout
pattern="%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} ${hostName} %c{1} %msg %throwable{7}%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<AppenderRef ref="console-log"/>
</Root>
</Loggers>
欢迎任何想法。感谢。
答案 0 :(得分:4)
在fatJar中,依赖项可以在META-INF中提供导致此问题的log4j-provider.properties,
在gradle任务中删除它:
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'project',
'Implementation-Version': project.version,
'Main-Class': 'com.sample.CLI'
}
baseName = project.name + '-all'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it).matching {
exclude 'META-INF/**.RSA'
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/log4j-provider.properties'
} } }
with jar
}
答案 1 :(得分:2)
此处描述了问题:https://issues.apache.org/jira/browse/LOG4J2-673
不幸的是,目前似乎只有maven-shade-plugin的解决方案:https://github.com/edwgiz/maven-shaded-log4j-transformer
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}${appSuffix}</finalName>
<transformers>
...
<transformer
implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer">
</transformer>
</transformers>
...
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
答案 2 :(得分:1)
LoggerContextFactory
将Log4j API绑定到其实现。 Log4j LogManager通过查找META-INF/log4j-provider.properties
的所有实例(标准java.util.Properties
文件)找到LoggerContextFactory,然后检查每个实例以验证它是否为Log4jAPIVersion属性指定了符合LogManager所需版本的值
加入胖jar,您也可以通过以下方式明确指定log4j2在您的应用程序中使用LoggerContextFactory
:
System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.core.impl.Log4jContextFactory")
或log4j-provider.properties
jar中包含的log4j-core
文件中指定的内容。
答案 3 :(得分:1)
Kinda参加这次聚会很晚,但我想我要补充一下情况,以防它对任何人有帮助。
我从大型项目的子类和罐子中构建自己的胖子罐。基本类运行,但是我得到了所有“无法识别的格式说明符”和所有。大多数答案都涉及mvn阴影或其他类似的颜色,所以这对我没有帮助。但是四处寻找,我了解到log4j-web.jar还包含Log4jPlugins.dat文件,从而导致了问题。从构建中删除它,一切都很好。
(而且我认为我的构建脚本是如此棘手,包括项目名称中的所有jar,例如“ log4j”的所有jar。)
答案 4 :(得分:0)
当您从IDE运行应用程序时,jar会在不嵌入依赖项的情况下自行运行,并且您不会遇到日志设置冲突。但是,当您将应用程序转换为胖jar时,所有依赖项将被注入到项目的jar文件中,而来自外部jar文件(依赖项)的log4j设置可能会发生冲突,而fatJar进程将它们合并为一个工件。
在这种情况下,我认为你的&#34; Log4j2Plugins.dat&#34;文件可能会有冲突。可以肯定的是,您可以使用zip编辑器打开fatJar文件(例如:7Zip),导航到fatJar中的路径,如下所示,并从fatJar中删除一个冲突的文件(您可以选择最小的一个)。运行fatJar并检查日志记录是否正常工作。
\ META-INF \组织\阿帕奇\记录\ log4j的\芯\配置\插件\ Log4j2Plugins.dat
现在我们可以检查依赖项(工件)并找到哪些包含&#34; Log4j2Plugins.dat&#34;文件。因此,您可以从构建工具中排除包含该文件的模块,然后您的fatJar创建过程将排除冲突的文件,并且您的新fatJar可以按预期开始记录。
在我的情况下,我的fatJar模块从Spring Boot导入了一些其他模块,当我排除冲突的日志库时,我的fatJar开始记录而没有任何错误。
configurations {
all*.exclude module: 'spring-boot'
all*.exclude module: 'spring-boot-starter-logging'
all*.exclude module: 'logback-classic'
all*.exclude module: 'commons-logging'
}