关于如何记录http请求所花费的时间的小问题。
为了避免混淆,这个问题是关于日志的(不是度量),这个问题是关于Webflux的,这个问题是关于出站呼叫的,我是客户端,试图呼叫服务器,我需要计时这个操作,但是从日志的角度来看。
基于这个片段,我使用:
@Override
public Mono<String> sendOutboundRequest() {
return webClient.post().retrieve().bodyToMono(String.class);
}
到目前为止,我尝试了.log()
,但这不是直接写时间花费,这个解决方案需要另一层解析时间戳从订阅和log4j时间的完成。
我也尝试了.metrics()
,这得到了时间,但这只生成指标,而不是日志。
我也尝试了一些围绕
的方法执行long start = System.nanoTime();
Mono<String> result = webClientIdms.post().retrieve().bodyToMono(String.class);
long end = System.nanoTime() - start;
LOGGER.info("this will not print the actual http request time " + end);
return result;
,但这不起作用,因为在响应式堆栈中,当响应式管道执行时,这不会计算请求的执行时间。
请问如何正确记录所花的时间?
谢谢
如果您希望以可重用的方式做到这一点,您可以利用ExchangeFilterFunction
。您可以在spring参考文档
ExchangeFilterFunction
的更多示例。下面是ExchangeFilterFunction
的一个示例实现,它将对WebClient
发出的每个外部api调用进行计时并记录结果。这是从MetricsWebClientFilterFunction
@Component
public class MetricsLoggingExchangeFilterFunction implements ExchangeFilterFunction {
private static final Logger LOGGER = LoggerFactory.getLogger(MetricsLoggingExchangeFilterFunction.class);
private static final String METRICS_WEBCLIENT_START_TIME = MetricsLoggingExchangeFilterFunction.class.getName() + ".START_TIME";
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request).doOnEach((signal) -> {
if (!signal.isOnComplete()) {
Long startTime = signal.getContextView().get(METRICS_WEBCLIENT_START_TIME);
long duration = System.currentTimeMillis() - startTime;
LOGGER.info("Downstream called taken {}ms", duration);
}
}).contextWrite(ctx -> ctx.put(METRICS_WEBCLIENT_START_TIME, System.currentTimeMillis()));
}
}
然后您可以将此添加到任何您想要使用提供的WebClient.Builder
记录持续时间的WebClient
实例中,即
WebClient.builder().filter(metricsLoggingExchangeFilterFunction).build()
您应该确保在响应式管道的执行阶段设置开始时间。你可以用mono_defer或mono_fromrunnable
AtomicLong start = new AtomicLong();
Mono.fromRunnable(() -> start.set(System.nanoTime())
.then(webClient.post()...)
.doOnNext(it -> LOGGEER.info("time spent {}",System.nanoTime() - start.get());