You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:27:18