diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java index 8cf2c91a6d..c4a6db3ef6 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java @@ -963,6 +963,22 @@ public Config withHighCardinalityTagsDetector(long threshold, Duration delay) { new HighCardinalityTagsDetector(MeterRegistry.this, threshold, delay)); } + /** + * Uses the supplied {@code Function} + * to create a new {@link HighCardinalityTagsDetector} for this registry. After + * the {@link HighCardinalityTagsDetector} is created, it also starts it. The + * implementation of the factory {@code Function} must pass the registry instance + * to one of the constructors of {@link HighCardinalityTagsDetector}. + * @param highCardinalityTagsDetectorFactory The {@code Function} that creates the + * {@link HighCardinalityTagsDetector} instance + * @return This configuration instance. + * @since 1.14.0 + */ + public Config withHighCardinalityTagsDetector( + Function highCardinalityTagsDetectorFactory) { + return withHighCardinalityTagsDetector(highCardinalityTagsDetectorFactory.apply(MeterRegistry.this)); + } + private Config withHighCardinalityTagsDetector(HighCardinalityTagsDetector newHighCardinalityTagsDetector) { if (highCardinalityTagsDetector != null) { highCardinalityTagsDetector.close(); diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/HighCardinalityTagsDetectorTests.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/HighCardinalityTagsDetectorTests.java index 97c6b45a1b..c36b2e7ebe 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/HighCardinalityTagsDetectorTests.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/HighCardinalityTagsDetectorTests.java @@ -15,15 +15,15 @@ */ package io.micrometer.core.instrument; -import java.time.Duration; -import java.util.function.Consumer; - import io.micrometer.common.lang.Nullable; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.time.Duration; +import java.util.function.Consumer; + import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -90,10 +90,23 @@ void shouldNotDetectNoTags() { assertThat(highCardinalityTagsDetector.findFirst()).isEmpty(); } + @Test + void shouldBeManagedThroughMeterRegistry() { + for (int i = 0; i < 4; i++) { + Counter.builder("test.counter").tag("index", String.valueOf(i)).register(registry).increment(); + } + + registry.config() + .withHighCardinalityTagsDetector( + r -> new HighCardinalityTagsDetector(r, 3, Duration.ofMinutes(1), testMeterNameConsumer)); + + await().atMost(Duration.ofSeconds(1)).until(() -> "test.counter".equals(testMeterNameConsumer.getName())); + } + private static class TestMeterNameConsumer implements Consumer { @Nullable - private String name; + private volatile String name; @Override public void accept(String name) {