Spring Boot2.6.6升级Log4j2.17.2含Routing标签触发配置错误
问题:Spring Boot 2.6.6升级Log4j2至2.17.2后,Routing标签触发日志配置错误
环境与依赖
当前使用Spring Boot 2.6.6,已引入以下Maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <version>${spring.boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>${spring.boot.version}</version> </dependency> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency>
问题现象
在日志配置文件中添加<Routing>标签后,触发运行时错误。最初的简化配置如下:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <property name="log-path" value="/path/" /> <!-- log levels precedence : ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF --> <property name="log-level" value="INFO" /> <Appenders> <appender name="console" target="SYSTEM_OUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" </pattern> </encoder> </appender> <Routing name="Routing"> <Routes pattern="$${ctx:docURN}"> <Route> <appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log-path}/filename.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log-path}/filename-%d{yyyy-MM-dd}.%i.log </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} tx.id= ${ctx:docURN} - %msg%n</pattern> </encoder> </appender> </Route> </Routes> </Routing> </Appenders> <Loggers> <logger name="com.name" level="${log-level}" additivity="false"> <appender-ref ref="LogFile" level="${log-level}" /> <appender-ref ref="Routing" level="${log-level}" /> </logger> <root level="info" additivity="false"> <appender-ref ref="Routing" /> </root> </Loggers> </Configuration>
错误信息:
java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:13 - no applicable action for [Appenders], current ElementPath is [[Configuration][Appenders]]
已尝试的调整
参照Log4j2官方示例调整配置后,问题仍未解决,调整后的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <Properties> <property name="log-path">/logfiles//</property> <!-- log levels precedence : ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF --> <property name="log-level">INFO</property> </Properties> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" /> </Console> <Routing name="Routing"> <Routes pattern="$${ctx:docURN}"> <Route> <RollingFile name="LogFile" append="true" fileName="${log-path}/-services.log" filePattern="${log-path}/-services-%d{yyyy-MM-dd}.log"> <PatternLayout> <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} tx.id= ${ctx:docURN} - %msg%n"></pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> </RollingFile> </Route> </Routes> </Routing> <Routing name="ErrorRouting"> <Routes pattern="$${ctx:docURN}"> <Route> <RollingFile name="ErrorLogFile" append="true" fileName="${log-path}/-services-error.log" filePattern="${log-path}/-services-error-%d{yyyy-MM-dd}.log"> <PatternLayout> <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} tx.id= ${ctx:docURN} - %msg%n"></pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> </RollingFile> </Route> </Routes> </Routing> <RollingFile name="ServerLogFile" fileName="${log-path}/Server.log" filePattern="${log-path}/Server-%d{yyyy-MM-dd}.log"> <PatternLayout> <Pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="info" additivity="false"> <AppenderRef ref="ServerLogFile" /> <AppenderRef ref="Routing" /> </Root> <Logger name="com.name" level="${log-level}" additivity="false"> <appender-ref ref="LogFile" level="${log-level}" /> <appender-ref ref="ErrorLogFile" level="error" /> <appender-ref ref="ServerLogFile" level="${log-level}" /> <appender-ref ref="Routing" level="${log-level}" /> <AppenderRef ref="ErrorRouting" level="error"/> </Logger> </Loggers> </Configuration>
解决方案
1. 修复依赖冲突
问题核心是同时引入了spring-boot-starter-logging(默认使用Logback)和spring-boot-starter-log4j2,导致日志框架冲突。Spring Boot中引入spring-boot-starter-log4j2时,会自动排除spring-boot-starter-logging,因此需要删除spring-boot-starter-logging的依赖声明,避免Logback被加载。
修正后的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>${spring.boot.version}</version> </dependency> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency>
2. 确保配置文件正确识别
Log4j2的配置文件默认命名为log4j2.xml,需放在src/main/resources目录下。如果使用其他名称,需要通过logging.config配置指定路径,避免Logback尝试解析该文件。
3. 修正配置文件错误
- 统一标签大小写:Log4j2配置中标签区分大小写,需统一使用
<AppenderRef>(不要混用小写的<appender-ref>)。 - 移除pattern中的多余引号:部分
<pattern>标签末尾存在多余的双引号,导致配置解析失败。 - 不要直接引用Routing内部的Appender:
<Routing>中的<RollingFile>是动态创建的,无法直接在<Loggers>中通过ref="LogFile"引用,应直接引用<Routing>Appender本身。 - 简化Routing配置:如果只是根据
docURN区分日志文件,无需创建多个Routing Appender,可在单个Routing中通过路由规则区分不同级别或日志类型。
修正后的配置示例:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <Properties> <property name="log-path">/logfiles/</property> <property name="log-level">INFO</property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" /> </Console> <!-- 统一Routing处理业务日志和错误日志 --> <Routing name="Routing"> <Routes pattern="$${ctx:docURN}"> <!-- 当docURN存在时,按租户生成日志文件 --> <Route> <RollingFile name="TenantLog-${ctx:docURN}" append="true" fileName="${log-path}/${ctx:docURN}-services.log" filePattern="${log-path}/${ctx:docURN}-services-%d{yyyy-MM-dd}.%i.log"> <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} tx.id=${ctx:docURN} - %msg%n" /> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> </RollingFile> </Route> <!-- 默认路由(docURN不存在时) --> <Route ref="ServerLogFile" key="default" /> </Routes> </Routing> <RollingFile name="ServerLogFile" fileName="${log-path}/Server.log" filePattern="${log-path}/Server-%d{yyyy-MM-dd}.%i.log"> <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" /> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="info" additivity="false"> <AppenderRef ref="Console" /> <AppenderRef ref="ServerLogFile" /> </Root> <Logger name="com.name" level="${log-level}" additivity="false"> <AppenderRef ref="Routing" /> </Logger> </Loggers> </Configuration>
内容的提问来源于stack exchange,提问作者code-match
相关产品推荐
相关产品推荐

