11

我正在开发一个使用 log4j2 日志记录的项目。在 intellij 中开发时,一切正常,并且日志记录按预期完成。log4j2.xml 通过在启动时通过 intellij 设置传递给 jvm 的 java 属性链接。但是一旦我尝试运行一个独立的 gradle 构建的 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>

欢迎任何想法。谢谢。

4

5 回答 5

5

在 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
}
于 2016-03-15T23:27:09.647 回答
4

问题在这里描述: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>
于 2016-04-07T07:17:31.737 回答
2

这个聚会有点晚了,但我想我会添加我的情况,以防它帮助任何人。

我用较大项目中的类和 jar 子集构建了自己的胖 jar。基本类运行,但我得到了所有“无法识别的格式说明符”等等。大多数答案都涉及 mvn shade 或其他类似的,所以这对我没有帮助。但是四处寻找,我了解到 log4j-web.jar 还包含 Log4jPlugins.dat 文件,从而导致了问题。从构建中删除它,一切都很好。

(而且我认为我的构建脚本非常棘手,包括按项目名称列出的所有 jar,例如“log4j”的所有 jar。)

于 2020-07-24T23:19:33.293 回答
1

LoggerContextFactoryLog4j API 绑定到它的实现。Log4j LogManager 通过定位META-INF/log4j-provider.properties标准java.util.Properties文件的所有实例来定位 LoggerContextFactory,然后检查每个以验证它为 Log4jAPIVersion 属性指定的值是否符合 LogManager 所需的版本。

LoggerContextFactory如果是胖 jar,您还可以通过以下方式明确指定要在应用程序中使用的 log4j2 :

System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.core.impl.Log4jContextFactory")

或在您的jar中log4j-provider.properties包含的文件中指定。log4j-core

于 2017-03-21T09:14:01.223 回答
0

当您从 IDE 运行应用程序时,jar 会自行运行而不嵌入依赖项,并且您不会遇到日志设置冲突。但是,当您将应用程序转换为 fat jar 时,所有依赖项都将被注入到项目的 jar 文件中,并且来自外部 jar 文件(依赖项)的 log4j 设置可能会发生冲突,而 fatJar 进程将它们合并为单个工件。

在这种情况下,我认为您的“Log4j2Plugins.dat”文件可能存在冲突。可以肯定的是,您可以使用 zip 编辑器(例如:7Zip)打开您的 fatJar 文件,如下所示导航到 fatJar 中的路径,然后从您的 fatJar 中删除其中一个冲突的文件(您可以选择最小的一个)。运行 fatJar 并检查日志是否正常工作。

\META-INF\org\apache\logging\log4j\core\config\plugins\Log4j2Plugins.dat

现在我们可以检查依赖项(工件)并找出其中哪些包含“Log4j2Plugins.dat”文件。因此,您可以从构建工具中排除具有该文件的模块,然后您的 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' }

于 2017-12-27T22:54:58.947 回答