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

Tomcat多Web应用中Log4j2配置文件日志输出异常排查

Tomcat多Web应用Log4j2日志异常问题

问题现象

在Tomcat中部署2个Web应用,各自拥有独立的Log4j2 Properties配置文件,但每个应用本地和Tomcat的lib目录都放置了log4j-api-2.18.0.jar和log4j-core-2.18.0.jar,出现以下异常:

  • 第二个应用的日志要么写入第一个应用的日志文件,要么仅输出到控制台,无法写入自身指定文件
  • 其中一份CMS配置的日志只输出到控制台,不写入文件
  • 另一份CMS配置的日志会写入会计应用的accounting.log,而非自身的cms_config.log

核心原因

  1. 类加载冲突:Tomcat的lib目录和应用WEB-INF/lib重复放置Log4j2核心包,导致Log4j2核心类被Tomcat公共类加载器加载,多个应用共享同一个Log4j2上下文,日志配置互相覆盖。
  2. Appender名称重复:第二份CMS配置和会计应用的配置都使用fileLogger作为RollingFileAppender的名称,共享上下文时后启动应用会复用先启动应用的同名Appender,导致日志写入错误文件。
  3. 第一份CMS配置语法错误:
    • 存在无效的空配置行appender.cmsConfig.filter=,导致Appender初始化失败
    • logger.cms_config.appenderRefs仅指定cmsConfig,但后续又添加了console的appenderRef,配置逻辑冲突

修复步骤

1. 清理重复的Log4j2包

  • 删除Tomcat/lib目录下的log4j-api-2.18.0.jar和log4j-core-2.18.0.jar
  • 仅保留每个应用WEB-INF/lib目录下的这两个包,让每个应用使用独立类加载器加载Log4j2,实现日志上下文隔离

2. 修正第一份CMS配置的语法错误

修改后的完整配置:

# Extra logging related to initialization of Log4j
# Set to debug or trace if log4j initialization is failing
status = debug
# Name of the configuration
name= CMS-Config

# Log files location
property.basePath = ${sys:catalina.home}/logs

appenders = cmsConfig, console

# RollingFileAppender name, pattern, path and rollover policy
appender.cmsConfig.type = RollingFile
appender.cmsConfig.name = cmsConfig_Logger
appender.cmsConfig.createOnDemand = true
appender.cmsConfig.fileName= ${basePath}/cms_config.log
appender.cmsConfig.filePattern= ${basePath}/app_%d{yyyyMMdd}.log.gz
appender.cmsConfig.layout.type = PatternLayout
appender.cmsConfig.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%l] - %msg%n
appender.cmsConfig.policies.type = Policies

# RollingFileAppender rotation policy
appender.cmsConfig.policies.startup.type = OnStartupTriggeringPolicy
appender.cmsConfig.policies.size.type = SizeBasedTriggeringPolicy
appender.cmsConfig.policies.size.size = 50MB
appender.cmsConfig.policies.time.type = TimeBasedTriggeringPolicy
appender.cmsConfig.policies.time.interval = 1
appender.cmsConfig.policies.time.modulate = true
appender.cmsConfig.strategy.type = DefaultRolloverStrategy
appender.cmsConfig.strategy.delete.type = Delete
appender.cmsConfig.strategy.delete.basePath = ${basePath}
appender.cmsConfig.strategy.delete.maxDepth = 10
appender.cmsConfig.strategy.delete.ifLastModified.type = IfLastModified

# Delete all files older than 3 days
appender.cmsConfig.strategy.delete.ifLastModified.age = 3d

# Console appender configuration
appender.console.type = Console
appender.console.name = consoleLogger
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss} %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green, DEBUG=blue} %c{1}:%L - %m%n

loggers = cms_config

# Classes in this package or sub packages will use ConsoleAppender and RollingFileAppender for logging         
logger.cms_config.name = com.dancik.cms
logger.cms_config.level = ERROR
logger.cms_config.additivity = false
logger.cms_config.appenderRefs = cmsConfig, console
logger.cms_config.appenderRef.cmsConfig.ref = cmsConfig_Logger
logger.cms_config.appenderRef.cmsConfig.level = ERROR
logger.cms_config.appenderRef.console.ref = consoleLogger

# Root logger level
rootLogger.level = debug
rootLogger.additivity = false
# Root logger referring to console appender
rootLogger.appenderRef.rolling.ref = cmsConfig_Logger
rootLogger.appenderRef.stdout.ref = consoleLogger

修改点:

  • 删除无效的appender.cmsConfig.filter=配置行
  • 将logger.cms_config.appenderRefs改为cmsConfig, console,与后续的appenderRef配置匹配

3. 修改第二份CMS配置的Appender名称

避免与会计应用的Appender名称重复,修改后的完整配置:

# Extra logging related to initialization of Log4j
# Set to debug or trace if log4j initialization is failing
status = ERROR
# Name of the configuration
name= CMS-Config

# Log files location
property.basePath = ${sys:catalina.home}/logs

# RollingFileAppender name, pattern, path and rollover policy
appender.cmsRolling.type = RollingFile
appender.cmsRolling.name = cmsFileLogger
appender.cmsRolling.createOnDemand = true
appender.cmsRolling.fileName= ${basePath}/cms_config.log
appender.cmsRolling.filePattern= ${basePath}/app_%d{yyyyMMdd}.log.gz
appender.cmsRolling.layout.type = PatternLayout
appender.cmsRolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%l] - %msg%n
appender.cmsRolling.policies.type = Policies

# RollingFileAppender rotation policy
appender.cmsRolling.policies.size.type = SizeBasedTriggeringPolicy
appender.cmsRolling.policies.size.size = 50MB
appender.cmsRolling.policies.time.type = TimeBasedTriggeringPolicy
appender.cmsRolling.policies.time.interval = 1
appender.cmsRolling.policies.time.modulate = true
appender.cmsRolling.strategy.type = DefaultRolloverStrategy
appender.cmsRolling.strategy.delete.type = Delete
appender.cmsRolling.strategy.delete.basePath = ${basePath}
appender.cmsRolling.strategy.delete.maxDepth = 10
appender.cmsRolling.strategy.delete.ifLastModified.type = IfLastModified

# Delete all files older than 3 days
appender.cmsRolling.strategy.delete.ifLastModified.age = 3d

# Console appender configuration
appender.console.type = Console
appender.console.name = consoleLogger
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss} %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green, DEBUG=blue} %c{1}:%L - %m%n

# Root logger level
rootLogger.level = ERROR
# Root logger referring to console appender
rootLogger.appenderRef.stdout.ref = consoleLogger
rootLogger.appenderRef.rolling.ref = cmsFileLogger

修改点:

  • 将Appender前缀从rolling改为cmsRolling
  • 将Appender名称从fileLogger改为cmsFileLogger
  • 同步修改rootLogger中对应的appenderRef引用

4. 验证配置

重启Tomcat后,检查两个应用的日志是否分别写入各自指定的文件,CMS应用日志是否同时输出到控制台和文件(符合配置逻辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:27:27