Spring WebFlux WebClient请求体日志缺失及配置方法咨询
问题:Spring WebFlux WebClient无法记录完整请求体
我在Spring WebFlux应用中尝试记录WebClient发送的请求体,已配置Logger和WebClient如下,但日志仅显示基础请求详情。请问配置中缺少什么?如何配置才能记录完整的序列化请求体详情?
WebClient配置
@Bean public WebClient webClient() { // Memory buffer configuration ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024 * 1024 * 50)) .build(); // Enable logging request details exchangeStrategies.messageWriters().stream() .filter(LoggingCodecSupport.class::isInstance) .forEach(writer -> ((LoggingCodecSupport) writer).setEnableLoggingRequestDetails(true)); ConnectionProvider provider = ConnectionProvider.builder("provider") .maxConnections(100) .maxIdleTime(Duration.ofSeconds(30)) .maxLifeTime(Duration.ofSeconds(30)) .pendingAcquireTimeout(Duration.ofSeconds(60)) .pendingAcquireMaxCount(-1) .evictInBackground(Duration.ofSeconds(30)) .lifo() .build(); HttpClient httpClient = HttpClient.create(provider) .wiretap("reactor.netty.http.client.HttpClient", LogLevel.INFO, AdvancedByteBufFormat.TEXTUAL) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000) .responseTimeout(Duration.ofSeconds(60)) .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(30, TimeUnit.SECONDS)) .addHandlerLast(new WriteTimeoutHandler(30, TimeUnit.SECONDS))); return WebClient.builder() .defaultHeader("Accept", MediaType.APPLICATION_JSON_VALUE) .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) .clientConnector(new ReactorClientHttpConnector(httpClient)) .exchangeStrategies(exchangeStrategies) .build(); }
Logger配置
<logger name="org.springframework.web.reactive.function.client.ExchangeFunctions" level="TRACE"/>
发送请求方法
public void sendRequest() { Map<String, Object> requestBody = Map.of("name", "example", "value", 123); String response = webClient.post() .uri("http://localhost:8080/v1/web-client/server-post") .bodyValue(requestBody) .retrieve() .bodyToMono(String.class) .block(); System.out.println("Response: " + response); }
观测日志
2025-01-15 19:08:17.108 TRACE 64787 --- [http-nio-8080-exec-5] o.s.w.r.f.client.ExchangeFunctions : [2d080393] HTTP POST http://localhost:8080/v1/web-client/server-post, headers=[Accept:"application/json, application/xml", Content-Type:"application/json"]
期望日志
[TRACE] org.springframework.web.reactive.function.client.ExchangeFunctions - [Request transformation] Transforming request body to serialized format. [DEBUG] org.springframework.web.reactive.function.client.ExchangeFunctions - Request Body: {"name":"example","value":123}
环境
- Spring Boot Version: 3.3
- Java Version: 17
- Reactor Netty: Spring Boot依赖提供的默认版本
- Logging Framework: Spring Boot默认的Logback
已执行的排查步骤
- 确认
org.springframework.web.reactive.function.client.ExchangeFunctions的日志级别已设为TRACE - 尝试将日志级别改为INFO
- 尝试移除wiretap配置,排查是否与Spring日志配置冲突
- 移除了wiretap配置(原步骤未完成)
解决方案
问题根源
- 编码器日志开关设置时机错误:你在
ExchangeStrategies构建完成后才设置enableLoggingRequestDetails,此时编码器已初始化,配置未生效。 - 缺少WebClient核心日志配置:仅配置
ExchangeFunctions不足以输出请求体,需要为WebClient本身开启TRACE级别日志。
修改后的配置
1. 调整WebClient的ExchangeStrategies配置
在构建ExchangeStrategies阶段直接配置编码器的日志开关,确保设置生效:
@Bean public WebClient webClient() { // 正确配置:在ExchangeStrategies构建阶段启用请求详情日志 ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() .codecs(configurer -> { configurer.defaultCodecs().maxInMemorySize(1024 * 1024 * 50); // 统一为所有默认编码器启用请求详情日志 configurer.defaultCodecs().enableLoggingRequestDetails(true); }) .build(); ConnectionProvider provider = ConnectionProvider.builder("provider") .maxConnections(100) .maxIdleTime(Duration.ofSeconds(30)) .maxLifeTime(Duration.ofSeconds(30)) .pendingAcquireTimeout(Duration.ofSeconds(60)) .pendingAcquireMaxCount(-1) .evictInBackground(Duration.ofSeconds(30)) .lifo() .build(); HttpClient httpClient = HttpClient.create(provider) // 若不需要Reactor Netty底层日志可注释,避免日志重复 // .wiretap("reactor.netty.http.client.HttpClient", LogLevel.INFO, AdvancedByteBufFormat.TEXTUAL) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000) .responseTimeout(Duration.ofSeconds(60)) .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(30, TimeUnit.SECONDS)) .addHandlerLast(new WriteTimeoutHandler(30, TimeUnit.SECONDS))); return WebClient.builder() .defaultHeader("Accept", MediaType.APPLICATION_JSON_VALUE) .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) .clientConnector(new ReactorClientHttpConnector(httpClient)) .exchangeStrategies(exchangeStrategies) .build(); }
2. 更新Logger配置
添加WebClient的TRACE级别日志配置,确保请求体日志能输出:
<logger name="org.springframework.web.reactive.function.client.ExchangeFunctions" level="TRACE"/> <logger name="org.springframework.web.reactive.function.client.WebClient" level="TRACE"/>
额外注意事项
- 若保留Reactor Netty的wiretap,建议将其日志级别设为
DEBUG或更低,避免与WebClient的日志输出重复。 - 对于大体积请求体,需确保
maxInMemorySize足够大,否则请求体可能被截断或无法完整记录。
内容的提问来源于stack exchange,提问作者백현명
相关产品推荐
相关产品推荐

