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

Log4j2在webMethods中按Appender生成独立日志异常排查

问题

在webMethods中使用Log4j2生成日志文件,需求是运行时由用户传入Logger名称、日志级别和消息,为每个Appender生成独立日志文件。当前配置和代码如下,但无论传入哪个Logger名称,所有日志都只写入最后一个Appender对应的EFG.log文件。

Log4j2 XML配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <RollingFile name="ROLL_ITLFileHandler" fileName="/esblogdata/logs/ITLFileHandler.log" filePattern="/esblogdata/logs/ITLFileHandler%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Appenders>
        <RollingFile name="ROLL_PublishCarrierEvent" fileName="/esblogdata/logs/PublishCarrierEvent.log" filePattern="/esblogdata/logs/PublishCarrierEvent%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Appenders>
        <RollingFile name="ROLL_ABC" fileName="/esblogdata/logs/ABC.log" filePattern="/esblogdata/logs/ABC%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Appenders>
        <RollingFile name="ROLL_EFG" fileName="/esblogdata/logs/EFG.log" filePattern="/esblogdata/logs/EFG%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="ITLFileHandler" level="DEBUG" additivity="true">
            <AppenderRef ref="ROLL_ITLFileHandler"/>
        </Logger>
        <Logger name="PublishCarrierEvent" level="DEBUG" additivity="true">
            <AppenderRef ref="ROLL_PublishCarrierEvent"/>
        </Logger>
        <Logger name="ABC" level="DEBUG" additivity="true">
            <AppenderRef ref="ROLL_ABC"/>
        </Logger>
        <Logger name="EFG" level="DEBUG" additivity="true">
            <AppenderRef ref="ROLL_EFG"/>
        </Logger>
        <Root level="DEBUG">
            <AppenderRef ref="ROLL_ITLFileHandler"/>
            <AppenderRef ref="ROLL_PublishCarrierEvent"/>
            <AppenderRef ref="ROLL_ABC"/>
            <AppenderRef ref="ROLL_EFG"/>
        </Root>
    </Loggers>
</Configuration>

Java日志写入代码

//Set Level - severity received from user in in run time as INFO, DEBUG etc.,
Level level = Level.getLevel(severity);         
ConfigurationFactory factory =  XmlConfigurationFactory.getInstance();

//LOG4J_CFG points to the location where log4j2 XML is kept
ConfigurationSource configurationSource = new ConfigurationSource(new FileInputStream(new File(LOG4J_CFG)));
Configuration configuration = factory.getConfiguration(null, configurationSource);  

// Get context instance
LoggerContext context = new LoggerContext("test");          

//Start logging system
context.start(configuration);
                
// Get a reference for logger (logger name will be passed in runtime by user which will be similar to the Logger name Ex: ITLFilehandler, ABC, XYZ in above XML
Logger logger = context.getLogger(loggerName);
logger.log(level, finalMessage);            
context.close();
解决方案

问题根源

  1. XML配置错误:Log4j2规范要求所有Appender必须定义在同一个<Appenders>标签内,多个独立的<Appenders>标签会导致只有最后一个标签内的配置被加载,前面的Appender全部被忽略,最终所有日志都只能写入最后一个Appender对应的文件。
  2. 代码设计不合理:每次日志请求都创建并关闭LoggerContext,违背Log4j2最佳实践,不仅浪费资源,还可能引发配置加载异常。

修复步骤

1. 修正Log4j2 XML配置

将所有Appender合并到同一个<Appenders>标签下,并调整Logger的additivity属性避免日志重复输出:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <RollingFile name="ROLL_ITLFileHandler" fileName="/esblogdata/logs/ITLFileHandler.log" filePattern="/esblogdata/logs/ITLFileHandler%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
        <RollingFile name="ROLL_PublishCarrierEvent" fileName="/esblogdata/logs/PublishCarrierEvent.log" filePattern="/esblogdata/logs/PublishCarrierEvent%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
        <RollingFile name="ROLL_ABC" fileName="/esblogdata/logs/ABC.log" filePattern="/esblogdata/logs/ABC%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
        <RollingFile name="ROLL_EFG" fileName="/esblogdata/logs/EFG.log" filePattern="/esblogdata/logs/EFG%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="ITLFileHandler" level="DEBUG" additivity="false">
            <AppenderRef ref="ROLL_ITLFileHandler"/>
        </Logger>
        <Logger name="PublishCarrierEvent" level="DEBUG" additivity="false">
            <AppenderRef ref="ROLL_PublishCarrierEvent"/>
        </Logger>
        <Logger name="ABC" level="DEBUG" additivity="false">
            <AppenderRef ref="ROLL_ABC"/>
        </Logger>
        <Logger name="EFG" level="DEBUG" additivity="false">
            <AppenderRef ref="ROLL_EFG"/>
        </Logger>
        <Root level="DEBUG">
            <!-- 若不需要Root日志写入所有文件,可移除以下AppenderRef -->
            <!-- <AppenderRef ref="ROLL_ITLFileHandler"/>
            <AppenderRef ref="ROLL_PublishCarrierEvent"/>
            <AppenderRef ref="ROLL_ABC"/>
            <AppenderRef ref="ROLL_EFG"/> -->
        </Root>
    </Loggers>
</Configuration>
  • additivity="false":确保每个Logger的日志仅写入自身关联的Appender,不会被Root Logger重复输出。

2. 优化Java代码

复用全局LoggerContext,避免重复创建和销毁:

// 应用启动时初始化一次配置
static {
    System.setProperty("log4j.configurationFile", LOG4J_CFG);
}

// 日志写入方法
public void writeLog(String loggerName, String severity, String finalMessage) {
    Level level = Level.getLevel(severity);
    // 处理无效级别,默认使用DEBUG
    if (level == null) {
        level = Level.DEBUG;
    }
    // 使用Log4j2标准API获取Logger,自动关联全局Context
    Logger logger = LogManager.getLogger(loggerName);
    logger.log(level, finalMessage);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:24:51