Skip to content

Commit 40454df

Browse files
Handle prometheus names and labels consistently (#6049)
1 parent e6454f5 commit 40454df

File tree

4 files changed

+35
-17
lines changed

4 files changed

+35
-17
lines changed

Diff for: implementations/micrometer-registry-prometheus/src/main/java/io/micrometer/prometheusmetrics/PrometheusMeterRegistry.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import io.micrometer.core.instrument.*;
2121
import io.micrometer.core.instrument.cumulative.CumulativeFunctionCounter;
2222
import io.micrometer.core.instrument.cumulative.CumulativeFunctionTimer;
23-
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
2423
import io.micrometer.core.instrument.distribution.*;
24+
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
2525
import io.micrometer.core.instrument.distribution.pause.PauseDetector;
2626
import io.micrometer.core.instrument.internal.DefaultGauge;
2727
import io.micrometer.core.instrument.internal.DefaultLongTaskTimer;
@@ -54,7 +54,6 @@
5454

5555
import static java.util.concurrent.TimeUnit.NANOSECONDS;
5656
import static java.util.concurrent.TimeUnit.SECONDS;
57-
import static java.util.stream.Collectors.joining;
5857
import static java.util.stream.Collectors.toList;
5958
import static java.util.stream.StreamSupport.stream;
6059

@@ -591,11 +590,11 @@ private void applyToCollector(Meter.Id id, Consumer<MicrometerCollector> consume
591590

592591
meterRegistrationFailed(id,
593592
"Prometheus requires that all meters with the same name have the same"
594-
+ " set of tag keys. There is already an existing meter named '" + id.getName()
593+
+ " set of tag keys. There is already an existing meter named '" + getConventionName(id)
595594
+ "' containing tag keys ["
596595
+ String.join(", ", collectorMap.get(getConventionName(id)).getTagKeys())
597-
+ "]. The meter you are attempting to register" + " has keys ["
598-
+ getConventionTags(id).stream().map(Tag::getKey).collect(joining(", ")) + "].");
596+
+ "]. The meter you are attempting to register" + " has keys [" + String.join(", ", tagKeys)
597+
+ "].");
599598
return existingCollector;
600599
});
601600
}

Diff for: implementations/micrometer-registry-prometheus/src/main/java/io/micrometer/prometheusmetrics/PrometheusNamingConvention.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public PrometheusNamingConvention(String timerSuffix) {
4545
*/
4646
@Override
4747
public String name(String name, Meter.Type type, @Nullable String baseUnit) {
48-
String conventionName = NamingConvention.snakeCase.name(name, type, baseUnit);
48+
String conventionName = PrometheusNaming.prometheusName(name);
4949

5050
switch (type) {
5151
case COUNTER:
@@ -85,7 +85,7 @@ else if (!conventionName.endsWith("_seconds")) {
8585
*/
8686
@Override
8787
public String tagKey(String key) {
88-
return PrometheusNaming.sanitizeLabelName(key);
88+
return PrometheusNaming.sanitizeLabelName(PrometheusNaming.prometheusName(key));
8989
}
9090

9191
}

Diff for: implementations/micrometer-registry-prometheus/src/test/java/io/micrometer/prometheusmetrics/PrometheusMeterRegistryTest.java

+27-8
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,42 @@ void metersWithSameNameAndDifferentTagsContinueSilently() {
7070
}
7171

7272
@Test
73-
void meterRegistrationFailedListenerCalledOnSameNameDifferentTags() throws InterruptedException {
73+
void meterRegistrationFailedListenerCalledOnSameNameDifferentTagsWithEmptyTags() throws InterruptedException {
7474
CountDownLatch failedLatch = new CountDownLatch(1);
7575
registry.config().onMeterRegistrationFailed((id, reason) -> failedLatch.countDown());
7676
registry.counter("my.counter");
77-
registry.counter("my.counter", "k", "v").increment();
77+
registry.counter("my.counter", "test.k1", "v1").increment();
7878

7979
assertThat(failedLatch.await(1, TimeUnit.SECONDS)).isTrue();
8080

81-
assertThatThrownBy(() -> registry.throwExceptionOnRegistrationFailure().counter("my.counter", "k1", "v1"))
81+
assertThatThrownBy(() -> registry.throwExceptionOnRegistrationFailure().counter("my.counter", "test.k2", "v2"))
82+
.isInstanceOf(IllegalArgumentException.class)
83+
.hasMessage(
84+
"Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter named 'my_counter' containing tag keys []. The meter you are attempting to register has keys [test_k2].");
85+
86+
assertThatThrownBy(() -> registry.counter("my.counter", "test.k3", "v3"))
8287
.isInstanceOf(IllegalArgumentException.class)
83-
.hasMessageStartingWith(
84-
"Prometheus requires that all meters with the same name have the same set of tag keys.");
88+
.hasMessage(
89+
"Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter named 'my_counter' containing tag keys []. The meter you are attempting to register has keys [test_k3].");
90+
}
91+
92+
@Test
93+
void meterRegistrationFailedListenerCalledOnSameNameDifferentTagsWithNonEmptyTags() throws InterruptedException {
94+
CountDownLatch failedLatch = new CountDownLatch(1);
95+
registry.config().onMeterRegistrationFailed((id, reason) -> failedLatch.countDown());
96+
registry.counter("my.counter", "test.k1", "v1");
97+
registry.counter("my.counter", "k", "v").increment();
8598

86-
assertThatThrownBy(() -> registry.counter("my.counter", "k2", "v2"))
99+
assertThat(failedLatch.await(1, TimeUnit.SECONDS)).isTrue();
100+
101+
assertThatThrownBy(() -> registry.throwExceptionOnRegistrationFailure().counter("my.counter", "test.k2", "v2"))
87102
.isInstanceOf(IllegalArgumentException.class)
88-
.hasMessageStartingWith(
89-
"Prometheus requires that all meters with the same name have the same set of tag keys.");
103+
.hasMessage(
104+
"Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter named 'my_counter' containing tag keys [test_k1]. The meter you are attempting to register has keys [test_k2].");
105+
106+
assertThatThrownBy(() -> registry.counter("my.counter")).isInstanceOf(IllegalArgumentException.class)
107+
.hasMessage(
108+
"Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter named 'my_counter' containing tag keys [test_k1]. The meter you are attempting to register has keys [].");
90109
}
91110

92111
@Test

Diff for: implementations/micrometer-registry-prometheus/src/test/java/io/micrometer/prometheusmetrics/PrometheusNamingConventionTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ class PrometheusNamingConventionTest {
3030

3131
@Test
3232
void formatName() {
33-
assertThat(convention.name("123abc/{:id}水", Meter.Type.GAUGE)).startsWith("_23abc___id__");
33+
assertThat(convention.name("123.abc/{:id}水", Meter.Type.GAUGE)).startsWith("_23_abc___id__");
3434
}
3535

3636
@Test
3737
void formatTagKey() {
38-
assertThat(convention.tagKey("123abc/{:id}水")).startsWith("_23abc___id__");
38+
assertThat(convention.tagKey("123.abc/{:id}水")).startsWith("_23_abc___id__");
3939
}
4040

4141
@Test

0 commit comments

Comments
 (0)