Reputation: 26473
I have a WebClient
that makes calls to the backend:
https://example.com/foo?q=1
https://example.com/foo?q=2
https://example.com/foo?q=3
I want to collect metrics across endpoints. Currently, every uri
is collected separately.
Is there is a way to configure MetricsWebClientFilterFunction
to achieve that?
Upvotes: 2
Views: 1492
Reputation: 26473
@checketts suggested using uri templates and this is ihmo way simpler solution.
So in WebClient instead of using:
.uri { uri -> uri.path("foo").queryParam("q", "1").build() }
I used:
.uri("foo?q={id}", "1")
Underneath the latter WebClient
sets attribute:
attribute(URI_TEMPLATE_ATTRIBUTE, uriTemplate);
which is later used in WebClientExchangeTags
:
String uri = (String) request.attribute(URI_TEMPLATE_ATTRIBUTE).orElseGet(() -> request.url().toString());
Upvotes: 4
Reputation: 26473
I added custom WebClientExchangeTagsProvider
and registered it as a bean:
class SameUriWebClientExchangeTagsProvider : WebClientExchangeTagsProvider {
override fun tags(request: ClientRequest, response: ClientResponse?, throwable: Throwable?): Iterable<Tag> {
val method = WebClientExchangeTags.method(request)
val uri = tag(request)
val clientName = WebClientExchangeTags.clientName(request)
val status = WebClientExchangeTags.status(response, throwable)
val outcome = WebClientExchangeTags.outcome(response)
return listOf(method, uri, clientName, status, outcome)
}
private fun tag(request: ClientRequest): Tag {
val uri = request.attribute(WebClient::class.java.name + ".uriTemplate")
.orElseGet {
request.url().toString()
} as String
return Tag.of("uri", URI(uri).path)
}
}
Upvotes: 0