Expose Metrics of Spring WebClient using Spring Boot Actuator

Last Updated:  May 3, 2022 | Published: February 19, 2020

Monitoring the outcome of your HTTP calls is essential in a distributed system. Increased response times or error status codes can break or slow down your application. That's why you should monitor them properly. If you use Spring WebClient as your HTTP client, there is no need to track this manually. With Spring Boot Actuator, there is a way to expose important metrics of your Spring WebClient automatically. With this blog post, you'll learn how to configure your Spring Boot application to use this automatic mechanism.

Spring Boot Project Setup

First, let's have a look at the project setup. The application uses both the spring-boot-starter-web and spring-boot-starter-webflux. Hence Spring Boot autoconfigures a Tomcat but also ensures to use non-blocking parts of WebFlux like the WebClient.

In addition, to actually expose metrics, we need the  spring-boot-starter-actuator dependency:

To demonstrate the usage of the WebClientand explore its metrics, the application hits two different API's during application startup:

We'll see the code for the two injected beans later on, but for now, all they do is to access a remote API on the Internet and return a JsonNode. The rather ugly try-catch is used to not break the application during startup as one API returns a 404 HTTP status code for the first execution.

This is intended to, later on, see that the collected metrics also include the different HTTP status codes.

Spring WebClient Configuration

Next comes the most important part:  the correct usage of the WebClient. To automatically report metrics, we must not manually construct the client like the following:

Even though this works fine for making HTTP calls, we won't get metrics from such instances out-of-the-box. We could configure these clients to use the pre-defined MetricsWebClientCustomizer, but there is a simpler solution…

Instead of creating WebClient instances from scratch (like above), we can inject an instance ofWebClient.Builder and start from there. This builder instance is already configured to report metrics automatically.

By the way, the same works for the RestTemplate using the RestTemplateBuilder respectively.

Given this pre-configured builder, we're defining a WebClient bean for the whole application to add general timeouts. This is optional, and we can also directly use WebClient.Builder within our classes:

Any Java class which makes HTTP calls can now inject thisWebClient and use it:

Another important thing to note is the construction of the URI for your HTTP call.

As we usually want the templated URI string like "/todos/{id}" for reporting and not multiple metrics e.g."/todos/1337"or "/todos/42". The WebClient offers several ways to construct the URI (overloaded .uri(...)),  which you can all use, except one. There is one version that takes Function<UriBuilder,URI> as an argument and can be used like this:

With this solution the WebClient doesn't know the URI template origin, as it gets passed the final URI. Using this approach, we would get metrics for each different invocation like:

Assuming we want URI templates within your reporting "/todos/{id}", use any URI construction, except the one which uses Function<UriBuilder,URI>.

Accessing WebClient Metrics with Spring Boot Actuator

Finally, we can expose the metricsendpoint for Spring Boot Actuator for a quick investigation in the browser with the following configuration inside our application.properties file:

Once we start the application, let all API calls finish and then access http://localhost:8080/actuator/metrics/http.client.requests, we get the following output:

This is a first glance of what we get out of the box: counting, timing & status codes.

Spring Boot Actuator provides different tags (clientName, uri, outcome, status) to further drill down in our monitoring system. Given these tags, we can create dashboards to visualize the response times and status codes per different clients over time.

We usually don't expose this endpoint for applications running in production and rather configure Spring Boot Actuator to export the metrics to a compatible monitoring system (e.g., Datadog or Prometheus).

For more content on Spring's WebClient, have a look at the following blog posts:

You can find the source code for this sample Spring Boot application on GitHub.

Have fun accessing Spring WebClient metrics,

Phil

>