Spring Web Reactive应用中CommonsRequestLoggingFilter与Log4j2日志不输出求助
嘿,我来帮你理清这个问题——CommonsRequestLoggingFilter 完全不能在 Spring Web Reactive 应用里用,这就是你配置后没看到日志的根本原因,和 Log4j2 的兼容性没关系哈。
为啥用不了?
CommonsRequestLoggingFilter 是专门给传统 Servlet 栈设计的过滤器,它完全依赖 Servlet API(比如 HttpServletRequest、HttpServletResponse 这些对象)。而 Spring Web Reactive 是基于非阻塞 Reactive 栈构建的,用的是 ServerHttpRequest/ServerHttpResponse 这类 Reactive 模型的接口,和 Servlet API 完全不兼容。所以哪怕你把这个过滤器配置得再对,在 Reactive 环境里它根本不会被加载执行,自然啥日志都出不来。
关于 commons-logging 兼容性的疑问
你担心的依赖问题其实不是障碍:CommonsRequestLoggingFilter 确实依赖 commons-logging,但 Spring 早就考虑到这点了——它提供了 spring-jcl 这个桥接包,能把 commons-logging 的日志调用自动转接到 Log4j2(或者你用的其他日志框架)。只要你的项目里引入了 Log4j2 依赖和 spring-jcl,日志桥接是能正常工作的,但前提是过滤器本身能在环境里跑起来,而 Reactive 环境满足不了这个前提。
替代方案:Reactive 环境下怎么记录请求日志?
既然 Servlet 过滤器用不了,给你几个靠谱的替代方式:
1. 自定义 WebFilter
WebFilter 是 Reactive 环境对应的过滤器模型,你可以自己写一个来记录请求信息,灵活性拉满:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; @Component public class ReactiveRequestLoggingFilter implements WebFilter { private static final Logger logger = LoggerFactory.getLogger(ReactiveRequestLoggingFilter.class); @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); logger.info("Received request >> Method: {}, Path: {}, Remote Address: {}, Headers: {}", request.getMethod(), request.getPath(), request.getRemoteAddress(), request.getHeaders()); return chain.filter(exchange); } }
这个过滤器会在每个请求进来时记录关键信息,日志会通过 SLF4J 自动桥接到你的 Log4j2 配置里。
2. 用 Spring Boot Actuator 的 HTTP Trace
如果你的项目是 Spring Boot 应用,可以引入 spring-boot-starter-actuator,然后启用 httptrace 端点(默认是关闭的,需要在配置里打开),它会自动记录请求和响应的详细信息。你还能通过配置把这些追踪信息输出到 Log4j2 日志里,不用自己写代码。
3. 开启框架内置日志
Spring Web Reactive 本身也有内置的日志开关,比如把 org.springframework.web.server.adapter.HttpWebHandlerAdapter 的日志级别设为 DEBUG,它会输出请求的基本信息。不过这种方式日志内容比较固定,灵活性不如自定义 WebFilter,适合快速排查问题用。
内容的提问来源于stack exchange,提问作者Poonam

