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

Spring3+Java8应用Log4j1转Log4j2后日志仅输出到控制台问题排查

Log4j 1.x迁移至Log4j2后日志输出异常排查

问题背景

为修复安全漏洞,将基于Java8的Spring3旧应用从Log4j 1.x迁移到Log4j2,应用运行正常但日志输出不符合预期:部分日志仅出现在控制台,未写入指定日志文件。预期控制台仅输出ERROR级日志,日志文件包含INFO、DEBUG级日志。@LOG_DIR@/@LOG_FILE_NAME@等变量已在构建阶段完成替换。

原Log4j 1.x配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="ERROR" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] [%c] %m%n" />
        </layout>
    </appender>

    <appender name="APPLOG" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="@LOG_DIR@/@LOG_FILE_NAME@" />
        <param name="Append" value="true" />
        <param name="MaxFileSize" value="15MB" />
        <param name="MaxBackupIndex" value="10" />
        <param name="Threshold" value="@THRESHOLD@" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] [%c] %m%n" />
        </layout>
    </appender>

    <appender name="AUDITLOG" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="@AUDIT_LOG_DIR@/@AUDIT_LOG_FILE_NAME@"/>
        <param name="Append" value="true"/>
        <param name="Threshold" value="INFO"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd-HH" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%t] %m%n"/>
        </layout>
   </appender>
   
    <category name="com.abc" additivity="false">
        <priority value="@THRESHOLD@" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="org.httpclient" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="org.springframework" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="com.mchange.v2" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="org.mortbay" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="org.apache" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="APPLOG" />
    </category>

    <category name="AUDIT_LOGGER" additivity="false">
        <priority value="INFO" />
        <appender-ref ref="AUDITLOG"/>
    </category>
    
    <!-- Setup the Root category -->
    <root>
        <priority value="@THRESHOLD@" />
        <appender-ref ref="APPLOG" />
    </root>
</log4j:configuration>

转换后的Log4j2配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <!--<Properties>
        <Property name="logPath">target/cucumber-logs</Property>
        <Property name="rollingFileName">cucumber</Property>
    </Properties>-->
    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %-5p [%t] [%c] %m%n"/>
            <ThresholdFilter level="ERROR"/>
        </Console>
        <RollingFile name="APPLOG" append="true"
                     fileName="@LOG_DIR@/@LOG_FILE_NAME@"
                     filePattern="@LOG_DIR@/@LOG_FILE_NAME@.%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="%d %-5p [%t] [%c] %m%n"/>
            <ThresholdFilter level="@THRESHOLD@"/>
            <SizeBasedTriggeringPolicy size="15 MB"/>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
        <RollingFile name="AUDITLOG" append="true"
                     fileName="@AUDIT_LOG_DIR@/@AUDIT_LOG_FILE_NAME@"
                     filePattern="@AUDIT_LOG_DIR@/@AUDIT_LOG_FILE_NAME@.%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="[%t] %m%n"/>
            <ThresholdFilter level="INFO"/>
                <!-- Causes a rollover once the date/time pattern no longer applies to the active file -->
            <TimeBasedTriggeringPolicy modulate="true"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!-- Category definitions -->
        <Logger name="com.abc" level="@THRESHOLD@" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.httpclient" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.springframework" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="com.mchange.v2" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.mortbay" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.apache" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="AUDIT_LOGGER" level="INFO" additivity="false">
            <AppenderRef ref="AUDITLOG"/>
        </Logger>

        <!-- Setup the Root category -->
        <Root level="DEBUG">
            <AppenderRef ref="APPLOG" level="@THRESHOLD@"/>
        </Root>
    </Loggers>
</Configuration>

问题排查与修复方案

1. Root Logger配置逻辑偏差

原Log4j1中Root Logger的优先级为@THRESHOLD@,直接关联APPLOG;但Log4j2配置中将Root Logger的level设为DEBUG,同时在AppenderRef上额外指定level="@THRESHOLD@"。这种双层过滤会导致:

  • 若@THRESHOLD@的值高于DEBUG(比如INFO),DEBUG级日志会被Root Logger拦截,无法到达APPLOG
  • 未被自定义Logger覆盖的日志会流向Root,最终无法写入文件,可能通过默认配置输出到控制台

修复:将Root Logger的level直接设为@THRESHOLD@,移除AppenderRef上的level属性,与原配置逻辑保持一致:

<Root level="@THRESHOLD@">
    <AppenderRef ref="APPLOG"/>
</Root>

2. RollingFileAppender滚动策略不符合原逻辑

原Log4j1的APPLOG仅基于文件大小滚动,最多保留10个备份;但Log4j2配置中filePattern包含日期格式,会自动启用时间滚动,导致滚动逻辑与原配置不一致,可能干扰日志写入。

修复:若仅需大小滚动,修改filePattern为仅包含序号后缀:

<RollingFile name="APPLOG" append="true"
             fileName="@LOG_DIR@/@LOG_FILE_NAME@"
             filePattern="@LOG_DIR@/@LOG_FILE_NAME@.%i">
    <PatternLayout pattern="%d %-5p [%t] [%c] %m%n"/>
    <ThresholdFilter level="@THRESHOLD@"/>
    <SizeBasedTriggeringPolicy size="15 MB"/>
    <DefaultRolloverStrategy max="10"/>
</RollingFile>

3. ThresholdFilter缺少明确匹配规则

Log4j2的ThresholdFilter默认行为可能因版本略有差异,建议明确添加onMatch和onMismatch属性,确保过滤逻辑生效:

<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>

额外检查点

  • 确认@THRESHOLD@变量替换后的值是否符合预期(如DEBUG/INFO)
  • 清理依赖:移除所有Log4j1依赖,确保仅保留Log4j2及log4j-1.2-api桥接包
  • 检查日志目录的读写权限,确保应用有写入权限
  • 启用Log4j2调试模式(在Configuration标签添加status="debug"),查看配置加载和日志路由的详细日志,定位未写入文件的具体日志来源

最终修复后的Log4j2配置示例

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %-5p [%t] [%c] %m%n"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>
        <RollingFile name="APPLOG" append="true"
                     fileName="@LOG_DIR@/@LOG_FILE_NAME@"
                     filePattern="@LOG_DIR@/@LOG_FILE_NAME@.%i">
            <PatternLayout pattern="%d %-5p [%t] [%c] %m%n"/>
            <ThresholdFilter level="@THRESHOLD@" onMatch="ACCEPT" onMismatch="DENY"/>
            <SizeBasedTriggeringPolicy size="15 MB"/>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
        <RollingFile name="AUDITLOG" append="true"
                     fileName="@AUDIT_LOG_DIR@/@AUDIT_LOG_FILE_NAME@"
                     filePattern="@AUDIT_LOG_DIR@/@AUDIT_LOG_FILE_NAME@.%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="[%t] %m%n"/>
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <TimeBasedTriggeringPolicy modulate="true"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="com.abc" level="@THRESHOLD@" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.httpclient" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.springframework" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="com.mchange.v2" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.mortbay" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="org.apache" level="INFO" additivity="false">
            <AppenderRef ref="APPLOG"/>
        </Logger>
        <Logger name="AUDIT_LOGGER" level="INFO" additivity="false">
            <AppenderRef ref="AUDITLOG"/>
        </Logger>

        <Root level="@THRESHOLD@">
            <AppenderRef ref="APPLOG"/>
        </Root>
    </Loggers>
</Configuration>

内容的提问来源于stack exchange,提问作者MadOverJava

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:21:07