'How can I generate Webclient Histogram Metrics
I want to capture metrics (number of calls, 95th percentile) about calls made from my backend service to other third party services. I am using WebClient to make these http calls. I couldn't find a specific property to enable WebClient Histogram metrics.
I have added MetricsWebClientFilterFunction to generate the metrics. Here is the logic -
WebClient webClient = WebClient.builder() .baseUrl(SERVICE_URL) .filter(new MetricsWebClientFilterFunction(meterRegistry, new DefaultWebClientExchangeTagsProvider(), "webClientCalls", AutoTimer.ENABLED)) .build();
Its generating only count and sum metrics. How can I generate histogram metrics for WebClient calls?
Here is the output in /actuator/prometheus endpoint -
webClientCalls_seconds_count{clientName="service_url",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 1.0 webClientCalls_seconds_sum{clientName="service_url",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 2.301044994
webClientCalls_seconds_max{clientName="service_url",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 0.0
Solution 1:[1]
Just implement AutoTimer interface and override apply method.
public final class AutoTimerHistogram implements AutoTimer {
@Override
public void apply(Timer.Builder builder) {
builder
.serviceLevelObjectives(
Duration.ofMillis(100),
Duration.ofMillis(500),
Duration.ofMillis(800),
Duration.ofMillis(1000),
Duration.ofMillis(1200))
.minimumExpectedValue(Duration.ofMillis(100))
.maximumExpectedValue(Duration.ofMillis(10000));
}
}
After that add it to your MetricsWebClientFilterFunction
MetricsWebClientFilterFunction metricsFilter =
new MetricsWebClientFilterFunction(
meterRegistry,
new DefaultWebClientExchangeTagsProvider(),
"custom.web.client",
autoTimerHistogram);
# TYPE custom_web_client_seconds histogram
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="0.1",} 0.0
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="0.5",} 0.0
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="0.8",} 1.0
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="1.0",} 1.0
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="1.2",} 1.0
custom_web_client_seconds_bucket{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",le="+Inf",} 1.0
custom_web_client_seconds_count{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",} 1.0
custom_web_client_seconds_sum{clientName="login.microsoftonline.com",method="POST",outcome="SUCCESS",status="200",uri="/common/oauth2/v2.0/token",} 0.646656087
Solution 2:[2]
Putting my discomfort aside (privacy, anyone?)...
Assuming your extension collates the Information, you might consider "pushing" to the server every time the browser starts / quits and then once again every hour or so (users hardly ever quite their browsers these days)... this would make REST much more logical.
If you aren't collating the information on the client side, you might prefer a WebSocket implementation that pushes data in real time.
However, whatever you decide, you would also want to decouple the API from the transmission layer.
This means that (ignoring authentication paradigms) the WebSockets and REST implementations would look largely the same and be routed to the same function that contains the actual business logic... a function you could also call from a script or from the terminal. The network layer details should be irrelevant as far as the API implementation is concerned.
As a last note: I would never knowingly install an extension that collects so much data on me. Especially since URLs often contain private information (used for REST API routing). Please reconsider if you want to take part in creating such a product... they cannot violate our privacy if we don't build the tools that make it possible.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Myst |
