首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何记录spring-webflux WebClient请求+响应详细信息(bodies、headers、elasped_time)?

如何记录spring-webflux WebClient请求+响应详细信息(bodies、headers、elasped_time)?
EN

Stack Overflow用户
提问于 2019-05-15 16:35:29
回答 2查看 8.3K关注 0票数 3

基本上,我希望使用Spring WebClient将请求/响应信息记录在一个包含主体/头部的日志中。

有了Spring RestTemplate,我们就可以用ClientHttpRequestInterceptor来做到这一点。我找到了用于Spring WebClientExchangeFilterFunction,但还没有设法以一种干净的方式做一些类似的事情。我们可以使用这个过滤器,记录请求,然后记录响应,但我需要在相同的日志跟踪上记录这两个请求。

此外,我还没能用ExchangeFilterFunction.ofResponseProcessor方法获得响应体。

我希望有一个这样的日志(使用ClientHttpRequestInterceptor的当前实现),其中包含我需要的所有信息:

{
    "@timestamp": "2019-05-14T07:11:29.089+00:00",
    "@version": "1",
    "message": "GET https://awebservice.com/api",
    "logger_name": "com.sample.config.resttemplate.LoggingRequestInterceptor",
    "thread_name": "http-nio-8080-exec-5",
    "level": "TRACE",
    "level_value": 5000,
    "traceId": "e65634ee6a7c92a7",
    "spanId": "7a4d2282dbaf7cd5",
    "spanExportable": "false",
    "X-Span-Export": "false",
    "X-B3-SpanId": "7a4d2282dbaf7cd5",
    "X-B3-ParentSpanId": "e65634ee6a7c92a7",
    "X-B3-TraceId": "e65634ee6a7c92a7",
    "parentId": "e65634ee6a7c92a7",
    "method": "GET",
    "uri": "https://awebservice.com/api",
    "body": "[Empty]",
    "elapsed_time": 959,
    "status_code": 200,
    "status_text": "OK",
    "content_type": "text/html",
    "response_body": "{"message": "Hello World!"}"
}

有没有人能用Spring WebClient做这样的事情?或者如何继续跟踪Spring WebClient的请求/响应问题?

EN

回答 2

Stack Overflow用户

发布于 2019-05-22 06:07:13

您可以使用filter(),如下所示:

this.webClient = WebClient.builder().baseUrl("your_url")
            .filter(logRequest())
            .filter(logResponse())
            .build();

private ExchangeFilterFunction logRequest() {
    return (clientRequest, next) -> {
        log.info("Request: {} {}", clientRequest.method(), clientRequest.url());
        clientRequest.headers()
                .forEach((name, values) -> values.forEach(value -> log.info("{}={}", name, value)));
        return next.exchange(clientRequest);
    };
}

private ExchangeFilterFunction logResponse() {
    return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
        log.info("Response: {}", clientResponse.headers().asHttpHeaders().get("property-header"));
        return Mono.just(clientResponse);
    });
}
票数 1
EN

Stack Overflow用户

发布于 2021-04-27 14:20:08

我认为您不能调用.bodyToMono两次(一次在过滤器中,然后在使用客户端的地方再次调用),因此您可能无法将其记录到过滤器中。至于其他细节。

WebClient配置:

@Configuration
class MyClientConfig {

    @Bean
    fun myWebClient(): WebClient {
        return WebClient
            .builder()
            .baseUrl(myUrl)
            .filter(MyFilter())
            .build()
    }
}

过滤器:

class MyFilter : ExchangeFilterFunction {

    override fun filter(request: ClientRequest, next: ExchangeFunction): Mono<ClientResponse> {
        return next.exchange(request).flatMap { response ->

            // log whenever you want here...
            println("request: ${request.url()}, response: ${response.statusCode()}")

            Mono.just(response)
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56144894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档