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
相关产品推荐
相关产品推荐

