重写CommonsRequestLoggingFilter后日志失效问题求助
问题原因
你重写CommonsRequestLoggingFilter的afterRequest方法时使用了匿名内部类,而Spring的CommonsRequestLoggingFilter通过getClass()获取Logger实例,这会导致匿名子类的Logger名称变为你的配置类内部类(例如com.mypackage.myproject.RequestLoggingConfiguration$1),而非父类org.springframework.web.filter.CommonsRequestLoggingFilter。你现有的日志级别配置仅针对父类Logger,导致beforeRequest中的调试日志因级别未开启无法输出,表现为日志完全失效。
解决方案
推荐两种优雅的解决方式:
方式一:在匿名类中复用父类Logger
直接获取父类的Logger实例,重写beforeRequest方法时使用该Logger输出日志,同时保留afterRequest的空实现:
@Bean public CommonsRequestLoggingFilter logFilter() { // 获取CommonsRequestLoggingFilter类的Logger final Log parentLogger = LogFactory.getLog(CommonsRequestLoggingFilter.class); CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter() { @Override protected void afterRequest(HttpServletRequest request, String message) { // 空实现,不输出请求结束日志 } @Override protected void beforeRequest(HttpServletRequest request, String message) { // 使用父类Logger输出请求开始日志 if (parentLogger.isDebugEnabled()) { parentLogger.debug(message); } } }; filter.setIncludeClientInfo(true); filter.setIncludeHeaders(true); filter.setIncludePayload(true); filter.setIncludeQueryString(true); filter.setBeforeMessagePrefix("Request started => "); filter.setAfterMessagePrefix("Request ended => "); return filter; }
方式二:创建独立子类继承CommonsRequestLoggingFilter
定义自定义子类,明确使用父类的Logger,并重写afterRequest为空实现:
public class CustomRequestLoggingFilter extends CommonsRequestLoggingFilter { // 固定使用父类的Logger实例 private static final Log logger = LogFactory.getLog(CommonsRequestLoggingFilter.class); @Override protected void afterRequest(HttpServletRequest request, String message) { // 空实现,禁用请求结束日志 } @Override protected void beforeRequest(HttpServletRequest request, String message) { if (logger.isDebugEnabled()) { logger.debug(message); } } }
然后在配置类中注册这个自定义Filter:
@Bean public CommonsRequestLoggingFilter logFilter() { CustomRequestLoggingFilter filter = new CustomRequestLoggingFilter(); filter.setIncludeClientInfo(true); filter.setIncludeHeaders(true); filter.setIncludePayload(true); filter.setIncludeQueryString(true); filter.setBeforeMessagePrefix("Request started => "); filter.setAfterMessagePrefix("Request ended => "); return filter; }
备选方案(不推荐)
若不想修改代码,可调整日志配置,将你的配置类的Logger级别设为DEBUG:
logging.level.com.mypackage.myproject.RequestLoggingConfiguration=DEBUG
或在log4j2.xml中添加:
<logger name="com.mypackage.myproject.RequestLoggingConfiguration"> <level value="DEBUG" /> </logger>
此方案弊端是匿名内部类名称可能随代码变化,维护性较差。
内容的提问来源于stack exchange,提问作者Basile ROUTIER
相关产品推荐
相关产品推荐

