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

Webflux如何分别记录请求成功/失败响应时间 解决doOnSuccess错误时触发问题

问题原因

Spring WebFlux 中 chain.filter(exchange) 返回的 Mono<Void> 的成功信号,仅代表请求处理链路已经完整执行完毕,和返回的HTTP状态码无关。不管接口返回2xx、4xx还是5xx,只要处理过程中没有抛出未捕获的异常导致链路中断,都会触发doOnSuccess回调。只有处理过程中出现未捕获的异常、链路异常终止时,才会触发错误信号的相关回调。

解决方案

可以通过两个维度区分成功/失败场景:

  • 用doOnError捕获链路异常终止的失败场景
  • 在doOnSuccess中读取响应的HTTP状态码,区分业务层面的成功/失败

修改后的代码如下:

public class RequestTimingFilter implements WebFilter {
  private static final HttpStatus.Series SUCCESS_SERIES = HttpStatus.Series.SUCCESSFUL;
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    if (exchange.getRequest().getPath().value().contains("something")) {
      long startMillis = System.currentTimeMillis();
      return chain
          .filter(exchange)
          // 处理链路正常执行完成的场景,按状态码区分成功失败
          .doOnSuccess(success -> {
              long cost = System.currentTimeMillis() - startMillis;
              HttpStatus status = exchange.getResponse().getStatusCode();
              if (status != null && status.series() == SUCCESS_SERIES) {
                  log.info("Api call success: {}ms, status: {}", cost, status.value());
              } else {
                  log.warn("Api call business failed: {}ms, status: {}", cost, status == null ? 0 : status.value());
              }
          })
          // 处理链路异常终止的场景
          .doOnError(ex -> {
              long cost = System.currentTimeMillis() - startMillis;
              log.error("Api call system error: {}ms, error msg: {}", cost, ex.getMessage(), ex);
          });
    }
    return chain.filter(exchange);
  }
}

如果需要更细的状态码区分,也可以自行调整判断逻辑,比如单独统计4xx、5xx的占比。

内容的提问来源于stack exchange,提问作者Garima Natany

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 18:36:04