2017-09-11 19 views
6

私はSpring 5 WebClientを使用してリクエストをログに記録しようとしています。Spring 5のWebClientコールのログ方法

(私は春5と春ブーツ2を使用しています)

コード瞬間に、そのように見えます。

try { 
      return webClient.get().uri(url, urlParams).exchange().flatMap(response -> response.bodyToMono(Test.class)) 
        .map(test -> xxx.set(test)); 

     } catch (RestClientException e) { 
      log.error("Cannot get counter from opus", e); 
      throw e; 
     } 
+0

あなたが今持っているコードを共有できますか? –

+0

@BrianClozelはこちらです – Seb

+0

ありがとう!あなたはログに記録したいものの例も与えられますか?リクエストURI? –

答えて

4

あなたは簡単にそれはあなたがWebClient.Builderを使用してWebClientを作成するときにだけカスタムlogRequestフィルタを追加しExchangeFilterFunction

を使用して行うことができます。

このようなフィルタの例と、それをWebClientに追加する方法を示します。

@Slf4j 
@Component 
public class MyClient { 

    private final WebClient webClient; 

    // Create WebClient instance using builder. 
    // If you use spring-boot 2.0, the builder will be autoconfigured for you 
    // with the "prototype" scope, meaning each injection point will receive 
    // a newly cloned instance of the builder. 
    public MyClient(WebClient.Builder webClientBuilder) { 
     webClient = webClientBuilder // you can also just use WebClient.builder() 
       .baseUrl("https://httpbin.org") 
       .filter(logRequest()) // here is the magic 
       .build(); 
    } 

    // Just example of sending request 
    public void send(String path) { 
     ClientResponse clientResponse = webClient 
       .get().uri(uriBuilder -> uriBuilder.path(path) 
         .queryParam("param", "value") 
         .build()) 
       .exchange() 
       .block(); 
     log.info("Response: {}", clientResponse.toEntity(String.class).block()); 
    } 

    // This method returns filter function which will log request data 
    private static ExchangeFilterFunction logRequest() { 
     return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { 
      log.info("Request: {} {}", clientRequest.method(), clientRequest.url()); 
      clientRequest.headers().forEach((name, values) -> values.forEach(value -> log.info("{}={}", name, value))); 
      return Mono.just(clientRequest); 
     }); 
    } 

} 

myClient.send("get");としてください。ログメッセージがあるはずです。

出力例:

Request: GET https://httpbin.org/get?param=value 
header1=value1 
header2=value2 
+0

完璧なソリューション! – Seb

+0

IMOでは、 'block()'を呼び出すとwebclientを使用する目的が無効になります。フィルタを使用してリクエストを記録することはできますが、ブロックせずに 'Mono 'からどのようにレスポンスを記録するのかはわかりません。 –

+0

@PavanKumarここの 'block()'呼び出しはデモ目的のためのものです。とにかくリクエストロギングフィルタが機能します。レスポンスを記録するには別の['ExchangeFilterFunction'](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/reactive/function/client/ExchangeFilterFunction.html#)を記述することができます。 ofResponseProcessor-java.util.function.Function-)、応答を記録します。しかし、応答本体を記録するときは注意が必要です。そのため、ストリームの性質上、ラッパーなしで1回だけ使用できます。 – djxak

2

あなたは必ずしもreactor.ipc.netty.channel.ChannelOperationsHandlerがあなたのためにそれをしない、独自のロガーをロールバックする必要はありません。そのクラスのログシステムをDEBUGレベルでログするように設定してください:

2017-11-23 12:52:04.562 DEBUG 41449 --- [ctor-http-nio-5] r.i.n.channel.ChannelOperationsHandler : [id: 0x9183d6da, L:/127.0.0.1:57681 - R:localhost/127.0.0.1:8000] Writing object DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 0, cap: 0)) 
GET /api/v1/watch/namespaces/default/events HTTP/1.1 
user-agent: ReactorNetty/0.7.1.RELEASE 
host: localhost:8000 
accept-encoding: gzip 
Accept: application/json 
content-length: 0 

可能な限り、コードを書き留めない方がいいです。

+0

私は、デバッグのためのより簡単なオプションとして、限られた制御された環境でこのソリューションを好む。これはヘッダーなどに機密情報を公開する可能性があるため、必ずしも推奨されているとは限りません。カスタムフィルターを接続すると、そのような機密情報を解析して非表示にするオプションがあります。 –

+0

@PavanKumarどのような種類のロギングワイヤ伝送でも、「Authorization」のような機密ヘッダが公開される可能性があります。 OPはそれらを隠すことを要求しませんでしたが、もし* if *が必要なら、* then *コードが書かれるかもしれません。通常、このようなヘッダーはDEBUGレベルでログに記録できます。 –

関連する問題