You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

已执行的排查步骤

  1. 确认org.springframework.web.reactive.function.client.ExchangeFunctions的日志级别已设为TRACE
  2. 尝试将日志级别改为INFO
  3. 尝试移除wiretap配置,排查是否与Spring日志配置冲突
  4. 移除了wiretap配置(原步骤未完成)

解决方案

问题根源

  1. 编码器日志开关设置时机错误:你在ExchangeStrategies构建完成后才设置enableLoggingRequestDetails,此时编码器已初始化,配置未生效。
  2. 缺少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,提问作者백현명

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:50:09