Log4j2无法读取自定义配置文件,始终使用默认配置求助
问题描述
尝试让Log4j2打印debug日志,无论怎么操作(包括命令行指定配置文件)都只使用默认配置。运行mvn clean test -Dlog4j.debug时出现以下警告:
WARN StatusLogger Multiple logging implementations found:
Factory: org.apache.logging.log4j.core.impl.Log4jContextFactory, Weighting: 10
Factory: org.apache.logging.slf4j.SLF4JLoggerContextFactory, Weighting: 15
Using factory: org.apache.logging.slf4j.SLF4JLoggerContextFactory
项目包含Playwright、Spring Boot等依赖,不确定是否影响。
相关代码与配置
Java代码
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; class ExampleClass { static Logger logger = LogManager.getLogger(); void main() { logger.debug("Hello world") } }
Log4j2配置文件(src/main/resources/log4j2.xml)
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="trace"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="all"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
pom.xml核心依赖片段
<!-- Spring data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.2.0</version> </dependency> <!-- Spring boot web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.2.0</version> </dependency> <!-- Log4j --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.1</version> </dependency>
问题原因
- SLF4J上下文工厂抢占:警告明确显示系统选择了
SLF4JLoggerContextFactory而非Log4j2原生工厂,说明类路径中存在SLF4J与Log4j2的桥接冲突,导致Log4j2的配置被忽略。 - Spring Boot默认日志干扰:Spring Boot Starter依赖(如
spring-boot-starter-web、spring-boot-starter-data-jpa)默认引入spring-boot-starter-logging,该依赖使用SLF4J+Logback作为默认日志实现,会覆盖Log4j2的配置。 - 依赖传递冲突:Playwright等第三方依赖可能也引入了SLF4J相关实现,进一步加剧冲突。
解决步骤
1. 排除Spring Boot默认日志依赖
在所有Spring Boot Starter依赖中排除spring-boot-starter-logging,避免Logback干扰:
<!-- Spring data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.2.0</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Spring boot web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.2.0</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Spring boot test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>3.2.0</version> <scope>test</scope> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
2. 引入Spring Boot适配的Log4j2 Starter
替换原生Log4j2依赖为Spring Boot官方适配版本,自动处理依赖桥接与版本管理:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>3.2.0</version> </dependency>
注:添加此依赖后,可移除单独引入的log4j-api和log4j-core,因为Starter已包含并管理这两个依赖。
3. 排查并排除其他SLF4J冲突
运行mvn dependency:tree查看依赖树,找出其他引入SLF4J实现的依赖(如Playwright),排除对应的冲突依赖:
<!-- Playwright --> <dependency> <groupId>com.microsoft.playwright</groupId> <artifactId>playwright</artifactId> <version>1.39.0</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> </exclusions> </dependency>
4. 验证配置生效
重新运行项目或执行mvn clean test -Dlog4j.debug,若看到以下日志,说明Log4j2配置已生效:
INFO StatusLogger Log4j2 version 2.20.0 initialized from classpath resource [log4j2.xml]
5. 修复代码语法问题
Java入口方法需定义为public static void main(String[] args),且语句末尾需加分号:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; class ExampleClass { static Logger logger = LogManager.getLogger(); public static void main(String[] args) { logger.debug("Hello world"); } }
内容的提问来源于stack exchange,提问作者gbiz123

