2017-09-11 76 views
6

Próbuję zalogować wniosek robię przy użyciu Spring 5 WebClient, jakiś pomysł, jak mogę to osiągnąć?jak zalogować Spring 5 WebClient call

(używam sprężyny 5 i sprężyna bagażnika 2)

kodu wyglądać w tej chwili.

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

Czy możesz udostępnić kawałek kodu, który masz teraz? –

+0

@BrianClozel tutaj to jest – Seb

+0

Dzięki! Czy mógłbyś podać przykład tego, co chcesz logować? Identyfikator URI żądania? –

Odpowiedz

4

Można łatwo zrobić to używając ExchangeFilterFunction

Wystarczy dodać Zwyczaj logRequest filtra podczas tworzenia WebClient użyciu WebClient.Builder.

Oto przykład takiego filtra i jak go dodać do 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); 
     }); 
    } 

} 

Następnie wystarczy zadzwonić myClient.send("get"); i rejestrować komunikaty powinny być tam.

przykład wyjściowa:

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

idealne rozwiązanie !! – Seb

+0

IMO, powołując się na 'block()', pokonuje cel używania klienta WWW. Możemy rejestrować żądania za pomocą filtru, ale nie wiemy, jak zarejestrować odpowiedź z 'Mono ' bez blokowania. –

+0

@PavanKumar Wywołanie 'block()' służy wyłącznie do celów demonstracyjnych. Filtr rejestrowania żądań i tak zadziała. Aby zarejestrować odpowiedź, możesz napisać kolejną ['ExchangeFilterFunction'] (https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/reactive/function/client/ExchangeFilterFunction.html# ofResponseProcessor-java.util.function.Function-) i zapisz odpowiedź. Należy jednak zachować ostrożność podczas rejestrowania treści odpowiedzi - ze względu na jej strumień, może on zostać wykorzystany tylko raz bez opakowania. – djxak

2

Nie koniecznie muszą toczyć własne rejestratora, reactor.ipc.netty.channel.ChannelOperationsHandler zrobi to za Ciebie. Wystarczy skonfigurować system logowania dla tej klasy do logowania na poziomie 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 

jeden sposób, aby mieć mniej błędów jest nie pisać kod w miarę możliwości.

+0

Preferuję to rozwiązanie w ograniczonych i kontrolowanych środowiskach jako łatwiejszą opcję do debugowania. Nie zawsze jest to zalecane, ponieważ może ujawnić pewne poufne informacje w nagłówkach itp. Jeśli filtr niestandardowy jest podłączony, można przeanalizować i ukryć takie poufne informacje. –

+0

@PavanKumar Dowolna transmisja dziennika może ujawnić newralgiczne nagłówki, takie jak 'Authorization'. OP nie prosił o ich ukrycie, ale * jeśli * to wymaganie, * wtedy * kod może być zapisany. Zazwyczaj dopuszczalne jest rejestrowanie takich nagłówków na poziomie DEBUG. –