Trần Minh Phương
Trần Minh Phương

Reputation: 329

Get response time of web client web-flux

Just want to know if there is any way to get the response time of web client of spring web-flux?

Upvotes: 7

Views: 10365

Answers (3)

Mihai
Mihai

Reputation: 76

You could use the metrics from HttpClient:

HttpClient.create(...
.....
.metrics(true, CustomMetricsRecorder::new);

and:

public class CustomMetricsRecorder implements HttpClientMetricsRecorder {

    @Override
    public void recordDataReceivedTime(SocketAddress remoteAddress, String uri, String method, String status, Duration time) {
      System.out.println("Client metric: " + durationToString(time) + " - DataReceivedTime - " + uri + " " + method.toUpperCase());
    }
    @Override
    public void recordDataSentTime(SocketAddress remoteAddress, String uri, String method, Duration time) {
      System.out.println("Client metric: " + durationToString(time) + " - DataSentTime - " + uri + " " + method.toUpperCase());
    }
    @Override
    public void recordResponseTime(SocketAddress remoteAddress, String uri, String method, String status, Duration time) {
      System.out.println("Client metric: " + durationToString(time) + " - total req+resp - " + uri + " " + method.toUpperCase());
    }
    @Override
    public void recordDataReceived(SocketAddress remoteAddress, String uri, long bytes) {

    }
    @Override
    public void recordDataSent(SocketAddress remoteAddress, String uri, long bytes) {

    }
    @Override
    public void incrementErrorsCount(SocketAddress remoteAddress, String uri) {

    }
    @Override
    public void recordDataReceived(SocketAddress remoteAddress, long bytes) {

    }
    @Override
    public void recordDataSent(SocketAddress remoteAddress, long bytes) {

    }
    @Override
    public void incrementErrorsCount(SocketAddress remoteAddress) {

    }
    @Override
    public void recordTlsHandshakeTime(SocketAddress remoteAddress, Duration time, String status) {
      System.out.println("Client metric: " + durationToString(time) + " - TlsHandshakeTime - " + remoteAddress);
    }
    @Override
    public void recordConnectTime(SocketAddress remoteAddress, Duration time, String status) {
      System.out.println("Client metric: " + durationToString(time) + " - ConnectTime - " + remoteAddress);
    }
    @Override
    public void recordResolveAddressTime(SocketAddress remoteAddress, Duration time, String status) {
      System.out.println("Client metric: " + durationToString(time) + " - ResolveAddressTime - " + remoteAddress);
    }
  }

will print:

Client metric: 00:00.09 - ResolveAddressTime - xxxx.com:443
Client metric: 00:00.69 - ConnectTime - xxxx.com/52.210.218.144:443
Client metric: 00:00.87 - TlsHandshakeTime - xxxx/52.210.218.144:443
Client metric: 00:00.01 - DataSentTime - /xx/xx/v1 POST
Client metric: 00:00.14 - DataReceivedTime - /xx/xx/v1 POST
Client metric: 00:00.122 - total req+resp - /xx/xx/v1 POST

Upvotes: 2

Frischling
Frischling

Reputation: 2268

you also have the possibility to use elapsed() for this kind of thing

webClient.get().uri("/bla").retrieve()
     .bodyToMono(String.class)
     .elapsed()  // map the stream's time into our streams data
     .doOnNext(tuple -> log.info("Milliseconds for retrieving {}", tuple.getT1()))
     .map(Tuple2::getT2) // after outputting the measurement, return the data only

Note, that elapsed() elapses the whole reactive stream, so if you're doing something before the webClient... part, you should put an elapsed() before that - this resets the timer.

Upvotes: 8

Alexander Pankin
Alexander Pankin

Reputation: 3955

With Spring Boot you have built-in metrics for that. See issue.

If you want to implement your custom stopwatch, you could do something like this:

Mono<String> resultMono = Mono.subscriberContext()
        .flatMap(context -> webClient.get()
                .uri("/foo")
                .retrieve()
                .bodyToMono(String.class)
                .doOnNext(ignored -> log.info("Execution duration is {} ms",
                        System.currentTimeMillis() - context.<Long>get("stopWatch"))))
        .subscriberContext(context -> context.put("stopWatch",
                System.currentTimeMillis()));

Upvotes: 4

Related Questions