WildFly与Tomcat日志差异:如何配置Tomcat捕获Log4j2控制台输出至内部日志?
首先得搞清楚WildFly和Tomcat的差异:WildFly默认会把进程的标准输出/错误(也就是Log4j2控制台Appender输出的内容)自动重定向到它的服务器日志里,但Tomcat默认没做这个关联,所以得手动配置才能实现同样的效果。
下面分步骤来操作:
1. 先确认Log4j2的控制台输出目标
首先要保证你的Log4j2配置里,控制台Appender是输出到SYSTEM_OUT或SYSTEM_ERR,而不是自定义的流。比如你的log4j2.xml里应该有类似这样的配置:
<Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers>
这里target="SYSTEM_OUT"是关键,只有输出到标准输出流,Tomcat才能捕获到这些日志内容。
2. 修改Tomcat启动脚本,重定向标准输出/错误到内部日志
Tomcat默认不会把标准输出/错误写入它的内部日志文件,所以我们需要修改启动脚本,把这些流重定向到catalina.out(Tomcat的核心日志文件)。
针对Linux/macOS系统:
打开TOMCAT_HOME/bin/catalina.sh,先找到关于CATALINA_OUT的注释,确认它默认指向$CATALINA_BASE/logs/catalina.out(一般默认就是这个路径)。然后找到启动Tomcat的命令段,确保它把stdout和stderr都追加到这个文件里。如果原来的命令没有重定向,就修改成:
exec "$PRGDIR"/"$EXECUTABLE" start "$@" >> "$CATALINA_OUT" 2>&1
这样所有标准输出和错误都会被写入catalina.out,而且Tomcat自带的日志轮转机制也会自动处理这个文件。
针对Windows系统:
打开TOMCAT_HOME/bin/catalina.bat,同样确认CATALINA_OUT指向logs\catalina.out,然后修改启动命令,添加重定向:
start "Tomcat" "%_RUNJAVA%" %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" org.apache.catalina.startup.Bootstrap start >> "%CATALINA_OUT%" 2>&1
保存后重启Tomcat,Windows下的标准输出也会被写入catalina.out了。
3. 可选:统一日志格式(提升可读性)
如果你希望Log4j2的输出和Tomcat自身日志格式一致,方便查看,可以调整Log4j2的PatternLayout,匹配Tomcat默认的日志格式。比如Tomcat的catalina.out默认格式是:
2024-05-20 14:30:00,123 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1234] milliseconds
那你可以把Log4j2的Pattern改成:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %level [%t] %logger{36} - %msg%n"/>
这样两种日志风格统一,排查问题时更顺畅。
4. 验证配置是否生效
重启Tomcat后,触发Web应用的日志输出(比如访问一个接口,让应用打印日志),然后打开TOMCAT_HOME/logs/catalina.out,应该能看到Log4j2的控制台输出已经和Tomcat自身的日志一起出现在这个文件里了,和WildFly的效果一样。
另外要注意:如果你的Web应用用了Log4j2的AsyncConsoleAppender,也要确保它的target参数是SYSTEM_OUT/SYSTEM_ERR,不然可能无法被Tomcat捕获到。
内容的提问来源于stack exchange,提问作者Jonas

