diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java index 450a2850166..1aeaac95168 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java @@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.stream.Stream; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; @@ -109,10 +110,13 @@ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializing } private void applyFilters(MeterRegistry meterRegistry) { - if (meterRegistry instanceof AutoConfiguredCompositeMeterRegistry) { - return; + if (this.filters != null) { + Stream filters = this.filters.orderedStream(); + if (isAutoConfiguredComposite(meterRegistry)) { + filters = filters.filter(OnlyOnceLoggingDenyMeterFilter.class::isInstance); + } + filters.forEach(meterRegistry.config()::meterFilter); } - this.filters.orderedStream().forEach(meterRegistry.config()::meterFilter); } private void addToGlobalRegistryIfNecessary(MeterRegistry meterRegistry) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java index ed55ec967ab..3044c9bacca 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java @@ -16,6 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -28,29 +30,98 @@ import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; /** - * {@link MeterFilter} to log only once a warning message and deny a {@link Id Meter.Id}. + * {@link MeterFilter} to log a single warning message and deny a {@link Id Meter.Id} + * after a number of attempts for a given tag. * * @author Jon Schneider * @author Dmytro Nosan + * @author Phillip Webb * @since 2.0.5 */ public final class OnlyOnceLoggingDenyMeterFilter implements MeterFilter { - private static final Log logger = LogFactory.getLog(OnlyOnceLoggingDenyMeterFilter.class); + private final Log logger; private final AtomicBoolean alreadyWarned = new AtomicBoolean(); + private final String meterNamePrefix; + + private final int maximumTagValues; + + private final String tagKey; + private final Supplier message; + private final Set observedTagValues = ConcurrentHashMap.newKeySet(); + + /** + * Create a new {@link OnlyOnceLoggingDenyMeterFilter} instance. + * @param message the message to log + * @since 2.0.5 + * @deprecated since 3.4.12 in favor of + * {@link #OnlyOnceLoggingDenyMeterFilter(String, String, int, String)} + */ + @Deprecated(since = "3.4.12", forRemoval = true) public OnlyOnceLoggingDenyMeterFilter(Supplier message) { - Assert.notNull(message, "Message must not be null"); + this(null, null, null, 0, message); + } + + /** + * Create a new {@link OnlyOnceLoggingDenyMeterFilter} with an upper bound on the + * number of tags produced by matching metrics. + * @param meterNamePrefix the prefix of the meter name to apply the filter to + * @param tagKey the tag to place an upper bound on + * @param maximumTagValues the total number of tag values that are allowable + * @since 3.4.12 + */ + public OnlyOnceLoggingDenyMeterFilter(String meterNamePrefix, String tagKey, int maximumTagValues) { + this(meterNamePrefix, tagKey, maximumTagValues, (String) null); + } + + /** + * Create a new {@link OnlyOnceLoggingDenyMeterFilter} with an upper bound on the + * number of tags produced by matching metrics. + * @param meterNamePrefix the prefix of the meter name to apply the filter to + * @param tagKey the tag to place an upper bound on + * @param maximumTagValues the total number of tag values that are allowable + * @param hint an additional hint to add to the logged message or {@code null} + * @since 3.4.12 + */ + public OnlyOnceLoggingDenyMeterFilter(String meterNamePrefix, String tagKey, int maximumTagValues, String hint) { + this(null, meterNamePrefix, tagKey, maximumTagValues, + () -> String.format("Reached the maximum number of '%s' tags for '%s'.%s", tagKey, meterNamePrefix, + (hint != null) ? " " + hint : "")); + } + + private OnlyOnceLoggingDenyMeterFilter(Log logger, String meterNamePrefix, String tagKey, int maximumTagValues, + Supplier message) { + Assert.notNull(message, "'message' must not be null"); + Assert.isTrue(maximumTagValues >= 0, "'maximumTagValues' must be positive"); + this.logger = (logger != null) ? logger : LogFactory.getLog(OnlyOnceLoggingDenyMeterFilter.class); + this.meterNamePrefix = meterNamePrefix; + this.maximumTagValues = maximumTagValues; + this.tagKey = tagKey; this.message = message; } @Override public MeterFilterReply accept(Id id) { - if (logger.isWarnEnabled() && this.alreadyWarned.compareAndSet(false, true)) { - logger.warn(this.message.get()); + if (this.meterNamePrefix == null) { + return logAndDeny(); + } + String tagValue = id.getName().startsWith(this.meterNamePrefix) ? id.getTag(this.tagKey) : null; + if (tagValue != null && !this.observedTagValues.contains(tagValue)) { + if (this.observedTagValues.size() >= this.maximumTagValues) { + return logAndDeny(); + } + this.observedTagValues.add(tagValue); + } + return MeterFilterReply.NEUTRAL; + } + + private MeterFilterReply logAndDeny() { + if (this.logger.isWarnEnabled() && this.alreadyWarned.compareAndSet(false, true)) { + this.logger.warn(this.message.get()); } return MeterFilterReply.DENY; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java index 2f6be3b11ed..e285af60b04 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java @@ -16,7 +16,6 @@ package org.springframework.boot.actuate.autoconfigure.metrics.jersey; -import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.ObservationRegistry; import org.glassfish.jersey.micrometer.server.JerseyObservationConvention; import org.glassfish.jersey.micrometer.server.ObservationApplicationEventListener; @@ -70,12 +69,10 @@ public class JerseyServerMetricsAutoConfiguration { @Bean @Order(0) - public MeterFilter jerseyMetricsUriTagFilter(MetricsProperties metricsProperties) { - String metricName = this.observationProperties.getHttp().getServer().getRequests().getName(); - MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter( - () -> String.format("Reached the maximum number of URI tags for '%s'.", metricName)); - return MeterFilter.maximumAllowableTags(metricName, "uri", - metricsProperties.getWeb().getServer().getMaxUriTags(), filter); + public OnlyOnceLoggingDenyMeterFilter jerseyMetricsUriTagFilter(MetricsProperties metricsProperties) { + String meterNamePrefix = this.observationProperties.getHttp().getServer().getRequests().getName(); + int maximumTagValues = metricsProperties.getWeb().getServer().getMaxUriTags(); + return new OnlyOnceLoggingDenyMeterFilter(meterNamePrefix, "uri", maximumTagValues); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java index e88de01e032..0e201e6f6b0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.autoconfigure.observation.web.client; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; @@ -68,14 +67,13 @@ public class HttpClientObservationsAutoConfiguration { @Bean @Order(0) - MeterFilter metricsHttpClientUriTagFilter(ObservationProperties observationProperties, + OnlyOnceLoggingDenyMeterFilter metricsHttpClientUriTagFilter(ObservationProperties observationProperties, MetricsProperties metricsProperties) { Client clientProperties = metricsProperties.getWeb().getClient(); - String name = observationProperties.getHttp().getClient().getRequests().getName(); - MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter( - () -> "Reached the maximum number of URI tags for '%s'. Are you using 'uriVariables'?" - .formatted(name)); - return MeterFilter.maximumAllowableTags(name, "uri", clientProperties.getMaxUriTags(), denyFilter); + String meterNamePrefix = observationProperties.getHttp().getClient().getRequests().getName(); + int maxUriTags = clientProperties.getMaxUriTags(); + return new OnlyOnceLoggingDenyMeterFilter(meterNamePrefix, "uri", maxUriTags, + "Are you using 'uriVariables'?"); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java index cc0f331ca51..9ed7f00a35e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.autoconfigure.observation.web.reactive; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; @@ -64,12 +63,10 @@ public class WebFluxObservationAutoConfiguration { @Bean @Order(0) - MeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties) { - String name = this.observationProperties.getHttp().getServer().getRequests().getName(); - MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter( - () -> "Reached the maximum number of URI tags for '%s'.".formatted(name)); - return MeterFilter.maximumAllowableTags(name, "uri", metricsProperties.getWeb().getServer().getMaxUriTags(), - filter); + OnlyOnceLoggingDenyMeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties) { + String meterNamePrefix = this.observationProperties.getHttp().getServer().getRequests().getName(); + int maxUriTags = metricsProperties.getWeb().getServer().getMaxUriTags(); + return new OnlyOnceLoggingDenyMeterFilter(meterNamePrefix, "uri", maxUriTags); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java index df24a579eae..c8222237f2b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.autoconfigure.observation.web.servlet; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import jakarta.servlet.DispatcherType; @@ -87,13 +86,11 @@ public class WebMvcObservationAutoConfiguration { @Bean @Order(0) - MeterFilter metricsHttpServerUriTagFilter(ObservationProperties observationProperties, + OnlyOnceLoggingDenyMeterFilter metricsHttpServerUriTagFilter(ObservationProperties observationProperties, MetricsProperties metricsProperties) { - String name = observationProperties.getHttp().getServer().getRequests().getName(); - MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter( - () -> String.format("Reached the maximum number of URI tags for '%s'.", name)); - return MeterFilter.maximumAllowableTags(name, "uri", metricsProperties.getWeb().getServer().getMaxUriTags(), - filter); + String meterNamePrefix = observationProperties.getHttp().getServer().getRequests().getName(); + int maxUriTags = metricsProperties.getWeb().getServer().getMaxUriTags(); + return new OnlyOnceLoggingDenyMeterFilter(meterNamePrefix, "uri", maxUriTags); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java index e904ec2a280..fada36d96e8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java @@ -27,6 +27,7 @@ import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InOrder; @@ -124,6 +125,22 @@ class MeterRegistryPostProcessorTests { then(this.mockConfig).should().meterFilter(this.mockFilter); } + @Test + void postProcessAndInitializeOnlyAppliesLmiitedFiltersToAutoConfigured() { + OnlyOnceLoggingDenyMeterFilter onlyOnceFilter = mock(); + this.filters.add(this.mockFilter); + this.filters.add(onlyOnceFilter); + MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(CompositeMeterRegistries.AUTO_CONFIGURED, + createObjectProvider(this.properties), createObjectProvider(this.customizers), + createObjectProvider(this.filters), createObjectProvider(this.binders)); + AutoConfiguredCompositeMeterRegistry composite = new AutoConfiguredCompositeMeterRegistry(Clock.SYSTEM, + Collections.emptyList()); + postProcessAndInitialize(processor, composite); + assertThat(composite).extracting("filters") + .asInstanceOf(InstanceOfAssertFactories.ARRAY) + .containsExactly(onlyOnceFilter); + } + @Test void postProcessAndInitializeBindsTo() { given(this.mockRegistry.config()).willReturn(this.mockConfig); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilterTests.java new file mode 100644 index 00000000000..b671f1a3c85 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilterTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics; + +import java.util.Collections; + +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.Meter.Type; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.config.MeterFilterReply; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OnlyOnceLoggingDenyMeterFilter}. + * + * @author Phillip Webb + */ +class OnlyOnceLoggingDenyMeterFilterTests { + + @Test + @SuppressWarnings("removal") + void applyWithMssageOnly() { + OnlyOnceLoggingDenyMeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(() -> "Test"); + assertThat(filter.accept(meterId("test", "k", "v"))).isEqualTo(MeterFilterReply.DENY); + } + + @Test + void applyWhenNameDoesNotHavePrefixReturnsNeutral() { + OnlyOnceLoggingDenyMeterFilter filter = new OnlyOnceLoggingDenyMeterFilter("test", "k", 1); + assertThat(filter.accept(meterId("tset", "k", "v"))).isEqualTo(MeterFilterReply.NEUTRAL); + assertThat(filter).extracting("observedTagValues").asInstanceOf(InstanceOfAssertFactories.COLLECTION).isEmpty(); + } + + @Test + void applyWhenNameHasPrefixButNoTagKeyReturnsNeutral() { + OnlyOnceLoggingDenyMeterFilter filter = new OnlyOnceLoggingDenyMeterFilter("test", "k", 1); + assertThat(filter.accept(meterId("test", "k", "v"))).isEqualTo(MeterFilterReply.NEUTRAL); + assertThat(filter).extracting("observedTagValues") + .asInstanceOf(InstanceOfAssertFactories.COLLECTION) + .containsExactly("v"); + } + + @Test + void applyWhenNameHasPrefixAndTagKeyReturnsNeutralUntilLimit() { + OnlyOnceLoggingDenyMeterFilter filter = new OnlyOnceLoggingDenyMeterFilter("test", "k", 1); + assertThat(filter.accept(meterId("test", "k", "v1"))).isEqualTo(MeterFilterReply.NEUTRAL); + assertThat(filter.accept(meterId("test", "k", "v2"))).isEqualTo(MeterFilterReply.DENY); + assertThat(filter.accept(meterId("test", "k", "v3"))).isEqualTo(MeterFilterReply.DENY); + assertThat(filter).extracting("observedTagValues") + .asInstanceOf(InstanceOfAssertFactories.COLLECTION) + .containsExactly("v1"); + } + + private Meter.Id meterId(String name, String tagKey, String tagValue) { + MeterRegistry registry = new SimpleMeterRegistry(); + Meter meter = Meter.builder(name, Type.COUNTER, Collections.emptyList()) + .tag(tagKey, tagValue) + .register(registry); + return meter.getId(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java index 98d99b3e139..4f8b9ddb914 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java @@ -117,7 +117,7 @@ class RestClientObservationConfigurationTests { assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'http.client.requests'.") .contains("Are you using 'uriVariables'?"); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java index 752147c5479..1be5d783986 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java @@ -114,7 +114,7 @@ class RestTemplateObservationConfigurationTests { assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'http.client.requests'.") .contains("Are you using 'uriVariables'?"); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java index d2805aa7cc4..74cac64e9bc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java @@ -104,7 +104,7 @@ class WebClientObservationConfigurationTests { assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(1); // MeterFilter.maximumAllowableTags() works with prefix matching. assertThat(meterRegistry.find("http.client.requests.active").longTaskTimers()).hasSize(1); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'http.client.requests'.") .contains("Are you using 'uriVariables'?"); }); } @@ -116,7 +116,7 @@ class WebClientObservationConfigurationTests { assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(3); - assertThat(output).doesNotContain("Reached the maximum number of URI tags for 'http.client.requests'.") + assertThat(output).doesNotContain("Reached the maximum number of 'uri' tags for 'http.client.requests'.") .doesNotContain("Are you using 'uriVariables'?"); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java index 4e43b9164ac..641b3b6e4ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java @@ -64,7 +64,7 @@ class WebFluxObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context); assertThat(registry.get("http.server.requests").meters()).hasSizeLessThanOrEqualTo(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.server.requests'"); + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'http.server.requests'"); }); } @@ -78,7 +78,7 @@ class WebFluxObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context, "my.http.server.requests"); assertThat(registry.get("my.http.server.requests").meters()).hasSizeLessThanOrEqualTo(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'my.http.server.requests'"); + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'my.http.server.requests'"); }); } @@ -91,7 +91,8 @@ class WebFluxObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context); assertThat(registry.get("http.server.requests").meters()).hasSize(3); - assertThat(output).doesNotContain("Reached the maximum number of URI tags for 'http.server.requests'"); + assertThat(output) + .doesNotContain("Reached the maximum number of 'uri' tags for 'http.server.requests'"); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java index f7fb31c6717..48f52ad41fd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java @@ -135,7 +135,7 @@ class WebMvcObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context); assertThat(registry.get("http.server.requests").meters()).hasSizeLessThanOrEqualTo(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.server.requests'"); + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'http.server.requests'"); }); } @@ -149,7 +149,7 @@ class WebMvcObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context); assertThat(registry.get("my.http.server.requests").meters()).hasSizeLessThanOrEqualTo(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'my.http.server.requests'"); + assertThat(output).contains("Reached the maximum number of 'uri' tags for 'my.http.server.requests'"); }); } @@ -162,7 +162,8 @@ class WebMvcObservationAutoConfigurationTests { .run((context) -> { MeterRegistry registry = getInitializedMeterRegistry(context); assertThat(registry.get("http.server.requests").meters()).hasSize(3); - assertThat(output).doesNotContain("Reached the maximum number of URI tags for 'http.server.requests'"); + assertThat(output) + .doesNotContain("Reached the maximum number of 'uri' tags for 'http.server.requests'"); }); }