Java Spring Webflow,记录出站http调用所用的时间

2022-04-06 00:00:00 java spring-webflux

请回答有关如何记录http请求所用时间的小问题。

为了避免混淆,这个问题是关于日志(不是指标)的,这个问题是关于Webflow的,这个问题是关于出站呼叫的,我是客户端,正在尝试呼叫服务器,我需要对此操作计时,但从日志的角度来看。

基于我正在使用的这段代码:

 @Override
    public Mono<String> sendOutboundRequest() {
        return webClient.post().retrieve().bodyToMono(String.class);
    }

到目前为止,我尝试了.log(),但这并不是直接写入花费的时间,此解决方案需要从On SUBSCRIBE和ON COMPLETE OF 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 reference docs

上找到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.Builderie将其添加到要记录持续时间的任何WebClient实例中。

WebClient.builder().filter(metricsLoggingExchangeFilterFunction).build()

相关文章