I have a log4j.xml
with a customized appender like:
<appender name="console" class="com.example.MyAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m (%c{1}:%L)"/>
</layout>
</appender>
Recently I upgraded log4j
dependency to log4j2
, but still using this log4j.xml
and it works.
Now, I add a Spring Boot module in my project. Following Spring doc, I set my pom.xml
as
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.6.4</version>
</dependency>
And I also add arguments -Dlogging.config=log4j.xml -Dlog4j.configuration=log4j.xml -Dlog4j1.compatibility=true
for it.
But my Spring application shows the error and no log output:
ERROR StatusLogger Unknown object "logger" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"].
Seems log4j2
lib cannot recognize log4j.xml
, which means -Dlog4j1.compatibility=true
does not work for Spring Boot I think.
Any related config can be utilized or any workaround? Thanks.
TL;DR: The problem is that Log4j2 has two XML configuration factories (for the Log4j 1.x and Log4j 2.x formats), with the 2.x format having higher priority. You need to explicitly set the ConfigurationFactory
to use:
-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory
When a Spring Boot application starts Log4j2 is configured twice:
at the very beginning using Log4j2 automatic configuration. For this round you just need to set -Dlog4j1.compatibility=true
and call the config file log4j.xml
or call the file differently and set -Dlog4j.configuration
.
when Spring's environment is ready, Spring reconfigures Log4j2 programmatically using only a subset of Log4j2 automatic configuration. That is why this phase requires many manual settings:
-Dlogging.config=log4j.xml
: Spring does not look for a file named log4j.xml
,-Dlog4j1.compatibility=true
to activate the Log4j 1.x configuration factories,-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory
to increase the priority of the Log4j 1.x XML configuration factory.Remark: Using a native Log4j 1.x custom appender exposes you to all the problems (synchronization and performance) of the original Log4j 1.x. For example Log4j 1.x looses events during reconfiguration (as the one performed by Spring Boot), whereas Log4j 2.x does not.