部署在外部Tomcat 9的Spring Boot应用日志写入catalina.out而非log4j2.properties配置文件的问题排查求助
我看了你遇到的问题:把Spring Boot应用打包成war部署到Tomcat9后,日志没有写入log4j2.properties指定的/var/log/bt4test.log,反而都输出到了Tomcat的catalina.out里。结合你提供的配置和代码,我整理了几个常见的排查点和解决方案:
1. 先确认Log4j2配置文件是否被加载
你的log4j2.properties里设置了status = debug,这会让Log4j2输出自身的调试日志。你可以先去Tomcat的catalina.out里找类似这样的日志:
DEBUG StatusLogger Log4j2 configuration file found at [WEB-INF/classes/log4j2.properties]
如果看不到这类日志,说明配置文件没被正确加载:
- 确保
log4j2.properties放在src/main/resources目录下,打包后会自动进入war包的WEB-INF/classes路径 - 如果是解压部署war,手动检查
WEB-INF/classes里有没有这个配置文件 - 也可以在
pom.xml里明确指定配置文件位置(不过默认路径一般没问题)
2. 检查Tomcat进程的日志目录写入权限
你的日志路径是/var/log/bt4test.log,Tomcat运行的用户(通常是tomcat用户)需要对这个目录有写入权限:
- 执行命令查看目录权限:
ls -ld /var/log - 如果权限不足,执行:
sudo chown tomcat:tomcat /var/log(根据你的实际用户组调整) - 嫌麻烦的话,也可以把
log4j2.properties里的property.dir改成Tomcat自带的日志目录:${catalina.base}/logs,这个目录默认Tomcat有权限写入
3. 处理静态代码块的日志时机问题
看你的Bt4TestEndpoint里有个静态代码块:
static { logger.info("hello static"); }
Tomcat加载这个类的时候,静态代码块会立刻执行,但此时Spring Boot的日志配置还没完全初始化,Log4j2还没加载你的自定义规则,所以这部分日志会默认输出到catalina.out。
解决方法很简单,把静态块里的日志移到Spring的初始化回调里:
@PostConstruct public void init() { logger.info("hello post construct"); }
这样日志会在Spring Bean初始化完成后输出,此时Log4j2的配置已经生效了。
4. 确保完全排除Spring默认日志框架
你的pom.xml里已经排除了spring-boot-starter-logging,但最好再确认没有其他依赖偷偷引入了默认日志(比如commons-logging)。用Maven命令查看依赖树:
mvn dependency:tree | grep logging
如果发现还有额外的日志依赖,继续通过<exclusion>标签排除掉。
5. 调整Tomcat日志配置避免冲突
Tomcat默认用JUL(java.util.logging),可能和Log4j2存在冲突。你可以在Tomcat的conf/logging.properties里添加以下配置,让JUL的日志也转发到Log4j2:
handlers = org.apache.logging.log4j.jul.LogManagerFormatterHandler .level = INFO
记得在pom.xml里添加对应的依赖:
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jul</artifactId> </dependency>
最后验证步骤
- 调整完配置后重新打包war
- 部署到Tomcat并启动服务
- 访问
/hello接口,然后检查/var/log/bt4test.log是否有对应的日志 - 再看
catalina.out,确认不再输出应用的业务日志
内容的提问来源于stack exchange,提问作者Ron Harris

