如何用Log4j2接管Apache Tomcat 8.5的localhost_access_log日志?
嘿,我刚好碰到过一模一样的问题!你当前用的org.apache.catalina.valves.AccessLogValve是Tomcat原生的阀,它会直接往文件里写日志,根本不会走Log4j2的日志体系。要让访问日志也被Log4j2接管,得换个适配的阀或者调整配置,下面给你两种靠谱的解决方案:
方案一:用Tomcat官方的Log4j2 AccessLog阀(推荐)
这个方案最贴合Tomcat原有配置习惯,改动也不大:
先确认依赖包到位
确保你的Tomcatlib目录里已经有tomcat-juli-log4j2.jar(这是Tomcat和Log4j2集成的核心jar),还有Log4j2的基础依赖包:log4j-core.jar、log4j-api.jar、log4j-web.jar。既然你已经成功替换了其他日志系统,这一步应该没问题,但还是检查下更稳妥。替换server.xml里的AccessLogValve
把原来的原生阀换成Tomcat适配Log4j2的版本,注意新增的logName属性——它是用来关联Log4j2配置里的Logger名称的:<Valve className="org.apache.catalina.valves.Log4j2AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" logName="accessLog"/>在Log4j2配置文件里添加对应Logger和Appender
比如在你的log4j2.xml(或者其他格式的配置文件)里,专门给访问日志加一套处理规则:<Appenders> <!-- 用RollingFileAppender实现滚动日志,你可以根据需求调整格式和滚动策略 --> <RollingFile name="AccessLogAppender" fileName="${sys:catalina.base}/logs/localhost_access_log.txt" filePattern="${sys:catalina.base}/logs/localhost_access_log-%d{yyyy-MM-dd}.txt.gz"> <PatternLayout pattern="%h %l %u %t "%r" %s %b%n"/> <Policies> <TimeBasedTriggeringPolicy/> <!-- 按天滚动日志 --> </Policies> </RollingFile> </Appenders> <Loggers> <!-- 关联刚才Valve里指定的logName,additivity设为false避免重复输出 --> <Logger name="accessLog" level="info" additivity="false"> <AppenderRef ref="AccessLogAppender"/> </Logger> <!-- 保留你原来的其他Logger配置,比如Root Logger --> <Root level="info"> <AppenderRef ref="..."/> <!-- 这里填你原来的Appender名称 --> </Root> </Loggers>这里的
PatternLayout格式可以和Valve里的pattern保持一致,也可以只在Log4j2里定义,Valve里的pattern留空就行。
方案二:用Log4j2的RequestLogFilter(适合Web应用级配置)
如果你不想修改Tomcat全局的server.xml,可以在单个Web应用里配置这个Filter:
在web.xml里添加Filter配置
<filter> <filter-name>log4j2RequestLogFilter</filter-name> <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class> <init-param> <param-name>log4jConfiguration</param-name> <param-value>/WEB-INF/log4j2.xml</param-value> <!-- 指向你的Web应用里的Log4j2配置 --> </init-param> </filter> <filter-mapping> <filter-name>log4j2RequestLogFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 拦截所有请求 --> </filter-mapping>在Log4j2配置里启用RequestLog
在log4j2.xml里添加RequestLog的配置,把日志输出到你定义好的Appender:<RequestLog name="RequestLog"> <AppenderRef ref="AccessLogAppender"/> <PatternLayout pattern="%h %l %u %t "%r" %s %b%n"/> </RequestLog>这种方式是在Web应用层面拦截请求并记录,适合不想改动Tomcat全局配置的场景,但每个Web应用都需要单独配置。
最后验证
改完之后重启Tomcat,访问你的应用,检查logs目录下的访问日志是否正常生成,也可以看Log4j2的其他日志有没有相关输出,确认访问日志已经被Log4j2接管啦。
内容的提问来源于stack exchange,提问作者Shinance

