Affects: 6.0.5 When using WebClient with micrometer-observability (1.10.4), MeterFilter.maximumAllowableTags saves "none" uri value to observedTagValues Set (https://github.com/micrometer-metrics/micrometer/blob/main/micrometer-core/src/main/java/io/micrometer/core/instrument/config/MeterFilter.java#L254) what causes incorrectly reducing maximum number of tag values by 1.
This is starting in this line: https://github.com/spring-projects/spring-framework/blob/main/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java#L440
I'm not sure why it is working this way, but on the first invoke DefaultWebClient.exchange is using default values for tags like uri=none https://github.com/spring-projects/spring-framework/blob/main/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientRequestObservationConvention.java#L108 which is saved in that observedTagValues Set.
Here is an example in Spring Boot but I believe that the problem is in spring-framework itself:
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.stream.IntStream;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(classes = {TagLimitsForWebFluxTest.TagLimitsForWebFluxTestApplication.class}, webEnvironment = RANDOM_PORT,
properties = {"management.metrics.web.client.max-uri-tags=5",
"management.simple.metrics.export.enabled=true"})
class TagLimitsForWebFluxTest {
@LocalServerPort
int port;
@Autowired
WebClient.Builder builder;
@Test
void shouldLimitNumberOfTagsForWebFluxOutMetrics() throws Exception {
// given
WebClient client = builder.baseUrl("http://localhost:" + port).build();
// when
IntStream.range(0, 5).forEach(i -> client.get().uri("/" + i).retrieve().bodyToMono(String.class).block());
}
@SpringBootApplication
@RestController
static class TagLimitsForWebFluxTestApplication {
@GetMapping(path = "/{key}")
public Mono<String> index(@PathVariable Integer key) {
return Mono.just("OK");
}
}
}
Results in log:
Reached the maximum number of URI tags for 'http.client.requests'. Are you using 'uriVariables'?
even though, we used 5 uri tags and have limit for 5 uri tags.
In Spring Boot 2.7.X with Spring 5.X this problem occurs when we use 6 uri tags.
This is not a very significant problem as we can increase the value of management.metrics.web.client.max-uri-tags
by 1 after the Spring update, but I think it should be solved someday.
PS: I know that the correct way to use uri tags is (what the warning is about):
client.get().uri("/{key}", i).retrieve().bodyToMono(String.class).block()
Comment From: bclozel
I believe this is a duplicate of #30205, but for different reasons. The "http.client.requests.active"
observation records its tags when the observation starts. We can follow up on the other issue.