diff --git a/docs/modules/ROOT/pages/concepts/gauges.adoc b/docs/modules/ROOT/pages/concepts/gauges.adoc index 48010a6d93..2970dc3b8a 100644 --- a/docs/modules/ROOT/pages/concepts/gauges.adoc +++ b/docs/modules/ROOT/pages/concepts/gauges.adoc @@ -42,7 +42,7 @@ Note that, in this form, unlike other meter types, you do not get a reference to This pattern should be less common than the `DoubleFunction` form. Remember that frequent setting of the observed `Number` results in a lot of intermediate values that never get published. Only the _instantaneous value_ of the gauge at publish time is ever sent to the monitoring system. -WARNING: Attempting to construct a gauge with a primitive number or one of its `java.lang` object forms is always incorrect. These numbers are immutable. Thus, the gauge cannot ever be changed. Attempting to "`re-register`" the gauge with a different number does not work, as the registry maintains only one meter for each unique combination of name and tags. +WARNING: Attempting to construct a gauge with a primitive number or one of its `java.lang` object forms is always incorrect. These numbers are immutable. Thus, the gauge cannot ever be changed. Attempting to "re-register" the gauge with a different number does not work, as the registry maintains only one meter for each unique combination of name and tags. "Re-registering" a gauge can happen indirectly for example as the result of a `MeterFilter` modifying the name and/or the tags of two different gauges so that they will be the same after the filter is applied. == Gauge Fluent Builder diff --git a/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java b/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java index 51ab9b4e5f..b13abb0cc0 100644 --- a/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java +++ b/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java @@ -19,6 +19,7 @@ import io.micrometer.core.annotation.Timed; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.distribution.CountAtBucket; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; import io.micrometer.core.instrument.distribution.HistogramSnapshot; @@ -444,6 +445,31 @@ void strongReferenceGauges() { assertThat(registry.get("strong.ref").gauge().value()).isEqualTo(1.0); } + @Test + @DisplayName("gauges cannot be registered twice") + void gaugesCannotBeRegisteredTwice() { + AtomicInteger n1 = registry.gauge("my.gauge", new AtomicInteger(1)); + AtomicInteger n2 = registry.gauge("my.gauge", new AtomicInteger(2)); + + assertThat(registry.get("my.gauge").gauges()).hasSize(1); + assertThat(registry.get("my.gauge").gauge().value()).isEqualTo(1); + assertThat(n1).isNotNull().hasValue(1); + assertThat(n2).isNotNull().hasValue(2); + } + + @Test + @DisplayName("gauges cannot be registered effectively twice") + void gaugesCannotBeRegisteredEffectivelyTwice() { + registry.config().meterFilter(MeterFilter.ignoreTags("ignored")); + AtomicInteger n1 = registry.gauge("my.gauge", Tags.of("ignored", "1"), new AtomicInteger(1)); + AtomicInteger n2 = registry.gauge("my.gauge", Tags.of("ignored", "2"), new AtomicInteger(2)); + + assertThat(registry.get("my.gauge").gauges()).hasSize(1); + assertThat(registry.get("my.gauge").gauge().value()).isEqualTo(1); + assertThat(n1).isNotNull().hasValue(1); + assertThat(n2).isNotNull().hasValue(2); + } + } @DisplayName("long task timers")