Skip to content

Commit e570caa

Browse files
committed
WIP Prometheus client 1.5.0 same name, different label set
1 parent 8fdb3c4 commit e570caa

File tree

6 files changed

+93
-89
lines changed

6 files changed

+93
-89
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ newrelic-api = "5.14.0"
6060
# Kotlin 1.7 sample will fail from OkHttp 4.12.0 due to okio dependency being a Kotlin 1.9 module
6161
okhttp = "4.12.0"
6262
postgre = "42.7.9"
63-
prometheus = "1.4.3"
63+
prometheus = "1.5.0-SNAPSHOT"
6464
prometheusSimpleClient = "0.16.0"
6565
reactor = "2022.0.22"
6666
rest-assured = "5.5.7"

implementations/micrometer-registry-prometheus/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
description = 'MeterRegistry implementation for Prometheus using io.prometheus:prometheus-metrics-core. If you have compatibility issues with this module, you can go back to io.micrometer:micrometer-registry-prometheus-simpleclient that uses io.prometheus:simpleclient_common.'
22

3+
repositories {
4+
// TODO remove when Prometheus Java client 1.5.0 is released
5+
mavenLocal()
6+
}
7+
38
dependencies {
49
api(platform(libs.prometheusMetricsBom))
510

implementations/micrometer-registry-prometheus/src/main/java/io/micrometer/prometheusmetrics/MicrometerCollector.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,35 @@
4040
*/
4141
class MicrometerCollector implements MultiCollector {
4242

43-
private final Map<List<String>, Child> children = new ConcurrentHashMap<>();
43+
private final Map<Meter.Id, Child> children = new ConcurrentHashMap<>();
4444

4545
private final String conventionName;
4646

4747
private final Meter.Type meterType;
4848

49-
private final List<String> tagKeys;
49+
// private final List<String> tagKeys;
5050

5151
// take name to avoid calling NamingConvention#name after the call-site has already
5252
// done it
5353
MicrometerCollector(String name, Meter.Id id, NamingConvention convention) {
5454
this.conventionName = name;
5555
this.meterType = id.getType();
56-
this.tagKeys = id.getConventionTags(convention).stream().map(Tag::getKey).collect(toList());
56+
// this.tagKeys =
57+
// id.getConventionTags(convention).stream().map(Tag::getKey).collect(toList());
5758
}
5859

59-
public void add(List<String> tagValues, Child child) {
60-
children.put(tagValues, child);
60+
public void add(Meter.Id id, Child child) {
61+
children.put(id, child);
6162
}
6263

63-
public void remove(List<String> tagValues) {
64-
children.remove(tagValues);
64+
public void remove(Meter.Id id) {
65+
children.remove(id);
6566
}
6667

6768
public boolean isEmpty() {
6869
return children.isEmpty();
6970
}
7071

71-
public List<String> getTagKeys() {
72-
return tagKeys;
73-
}
74-
7572
Meter.Type getMeterType() {
7673
return meterType;
7774
}
@@ -81,7 +78,7 @@ public MetricSnapshots collect() {
8178
Map<String, Family> families = new HashMap<>();
8279

8380
for (Child child : children.values()) {
84-
child.samples(conventionName, tagKeys)
81+
child.samples(conventionName)
8582
.forEach(family -> families.compute(family.getConventionName(),
8683
(name, matchingFamily) -> matchingFamily != null
8784
? matchingFamily.addSamples(family.dataPointSnapshots) : family));
@@ -97,7 +94,7 @@ public MetricSnapshots collect() {
9794

9895
interface Child {
9996

100-
Stream<Family<?>> samples(String conventionName, List<String> tagKeys);
97+
Stream<Family<?>> samples(String conventionName);
10198

10299
}
103100

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

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.micrometer.common.util.internal.logging.WarnThenDebugLogger;
1919
import io.micrometer.core.instrument.*;
20+
import io.micrometer.core.instrument.config.NamingConvention;
2021
import io.micrometer.core.instrument.cumulative.CumulativeFunctionCounter;
2122
import io.micrometer.core.instrument.cumulative.CumulativeFunctionTimer;
2223
import io.micrometer.core.instrument.distribution.*;
@@ -114,6 +115,10 @@ public PrometheusMeterRegistry(PrometheusConfig config, PrometheusRegistry regis
114115
config().onMeterRemoved(this::onMeterRemoved);
115116
}
116117

118+
private static List<String> tagKeys(Meter.Id id, NamingConvention convention) {
119+
return id.getConventionTags(convention).stream().map(Tag::getKey).collect(toList());
120+
}
121+
117122
private static List<String> tagValues(Meter.Id id) {
118123
return stream(id.getTagsAsIterable().spliterator(), false).map(Tag::getValue).collect(toList());
119124
}
@@ -212,11 +217,11 @@ public Counter newCounter(Meter.Id id) {
212217
long createdTimestampMillis = clock.wallTime();
213218
applyToCollector(id, (collector) -> {
214219
List<String> tagValues = tagValues(id);
215-
collector
216-
.add(tagValues, (conventionName, tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
217-
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
218-
getMetadata(conventionName, id.getDescription()), new CounterDataPointSnapshot(counter.count(),
219-
Labels.of(tagKeys, tagValues), counter.exemplar(), createdTimestampMillis))));
220+
List<String> tagKeys = tagKeys(id, config().namingConvention());
221+
collector.add(id, (conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
222+
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
223+
getMetadata(conventionName, id.getDescription()), new CounterDataPointSnapshot(counter.count(),
224+
Labels.of(tagKeys, tagValues), counter.exemplar(), createdTimestampMillis))));
220225
});
221226
return counter;
222227
}
@@ -229,7 +234,8 @@ public DistributionSummary newDistributionSummary(Meter.Id id,
229234
long createdTimestampMillis = clock.wallTime();
230235
applyToCollector(id, (collector) -> {
231236
List<String> tagValues = tagValues(id);
232-
collector.add(tagValues, (conventionName, tagKeys) -> {
237+
List<String> tagKeys = tagKeys(id, config().namingConvention());
238+
collector.add(id, (conventionName) -> {
233239
Stream.Builder<MicrometerCollector.Family<?>> families = Stream.builder();
234240

235241
final ValueAtPercentile[] percentileValues = summary.takeSnapshot().percentileValues();
@@ -322,17 +328,17 @@ protected <T> io.micrometer.core.instrument.Gauge newGauge(Meter.Id id, @Nullabl
322328
Gauge gauge = new DefaultGauge<>(id, obj, valueFunction);
323329
applyToCollector(id, (collector) -> {
324330
List<String> tagValues = tagValues(id);
331+
List<String> tagKeys = tagKeys(id, config().namingConvention());
325332
if (id.getName().endsWith(".info")) {
326-
collector.add(tagValues,
327-
(conventionName,
328-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
329-
family -> new InfoSnapshot(family.metadata, family.dataPointSnapshots),
330-
getMetadata(conventionName, id.getDescription()),
331-
new InfoDataPointSnapshot(Labels.of(tagKeys, tagValues)))));
333+
collector.add(id,
334+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
335+
family -> new InfoSnapshot(family.metadata, family.dataPointSnapshots),
336+
getMetadata(conventionName, id.getDescription()),
337+
new InfoDataPointSnapshot(Labels.of(tagKeys, tagValues)))));
332338
}
333339
else {
334-
collector.add(tagValues,
335-
(conventionName, tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
340+
collector.add(id,
341+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
336342
family -> new GaugeSnapshot(family.metadata, family.dataPointSnapshots),
337343
getMetadata(conventionName, id.getDescription()),
338344
new GaugeDataPointSnapshot(gauge.value(), Labels.of(tagKeys, tagValues), null))));
@@ -357,14 +363,13 @@ protected <T> FunctionTimer newFunctionTimer(Meter.Id id, T obj, ToLongFunction<
357363
long createdTimestampMillis = clock.wallTime();
358364
applyToCollector(id, (collector) -> {
359365
List<String> tagValues = tagValues(id);
360-
collector.add(tagValues,
361-
(conventionName,
362-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
363-
family -> new SummarySnapshot(family.metadata, family.dataPointSnapshots),
364-
getMetadata(conventionName, id.getDescription()),
365-
new SummaryDataPointSnapshot((long) ft.count(), ft.totalTime(getBaseTimeUnit()),
366-
Quantiles.EMPTY, Labels.of(tagKeys, tagValues), null,
367-
createdTimestampMillis))));
366+
List<String> tagKeys = tagKeys(id, config().namingConvention());
367+
collector.add(id,
368+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
369+
family -> new SummarySnapshot(family.metadata, family.dataPointSnapshots),
370+
getMetadata(conventionName, id.getDescription()),
371+
new SummaryDataPointSnapshot((long) ft.count(), ft.totalTime(getBaseTimeUnit()),
372+
Quantiles.EMPTY, Labels.of(tagKeys, tagValues), null, createdTimestampMillis))));
368373
});
369374
return ft;
370375
}
@@ -375,8 +380,9 @@ protected <T> FunctionCounter newFunctionCounter(Meter.Id id, T obj, ToDoubleFun
375380
long createdTimestampMillis = clock.wallTime();
376381
applyToCollector(id, (collector) -> {
377382
List<String> tagValues = tagValues(id);
378-
collector.add(tagValues, (conventionName,
379-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
383+
List<String> tagKeys = tagKeys(id, config().namingConvention());
384+
collector.add(id,
385+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
380386
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
381387
getMetadata(conventionName, id.getDescription()), new CounterDataPointSnapshot(fc.count(),
382388
Labels.of(tagKeys, tagValues), null, createdTimestampMillis))));
@@ -388,7 +394,8 @@ protected <T> FunctionCounter newFunctionCounter(Meter.Id id, T obj, ToDoubleFun
388394
protected Meter newMeter(Meter.Id id, Meter.Type type, Iterable<Measurement> measurements) {
389395
applyToCollector(id, (collector) -> {
390396
List<String> tagValues = tagValues(id);
391-
collector.add(tagValues, (conventionName, tagKeys) -> {
397+
List<String> tagKeys = tagKeys(id, config().namingConvention());
398+
collector.add(id, (conventionName) -> {
392399
Stream.Builder<MicrometerCollector.Family<?>> families = Stream.builder();
393400
List<String> statKeys = new ArrayList<>(tagKeys);
394401
statKeys.add("statistic");
@@ -464,7 +471,8 @@ private void addDistributionStatisticSamples(Meter.Id id, MicrometerCollector co
464471
HistogramSupport histogramSupport, Supplier<Exemplars> exemplarsSupplier, List<String> tagValues,
465472
boolean forLongTaskTimer) {
466473
long createdTimestampMillis = clock.wallTime();
467-
collector.add(tagValues, (conventionName, tagKeys) -> {
474+
List<String> tagKeys = tagKeys(id, config().namingConvention());
475+
collector.add(id, (conventionName) -> {
468476
Stream.Builder<MicrometerCollector.Family<?>> families = Stream.builder();
469477

470478
HistogramSnapshot histogramSnapshot = histogramSupport.takeSnapshot();
@@ -557,7 +565,7 @@ private Exemplar createExemplarWithNewValue(double newValue, Exemplar exemplar)
557565
private void onMeterRemoved(Meter meter) {
558566
MicrometerCollector collector = collectorMap.get(getConventionName(meter.getId()));
559567
if (collector != null) {
560-
collector.remove(tagValues(meter.getId()));
568+
collector.remove(meter.getId());
561569
if (collector.isEmpty()) {
562570
collectorMap.remove(getConventionName(meter.getId()));
563571
getPrometheusRegistry().unregister(collector);
@@ -591,16 +599,7 @@ private void applyToCollector(Meter.Id id, Consumer<MicrometerCollector> consume
591599
return existingCollector;
592600
}
593601

594-
List<String> tagKeys = getConventionTags(id).stream().map(Tag::getKey).collect(toList());
595-
if (existingCollector.getTagKeys().equals(tagKeys)) {
596-
consumer.accept(existingCollector);
597-
return existingCollector;
598-
}
599-
600-
meterRegistrationFailed(id, "Prometheus requires that all meters with the same name have the same"
601-
+ " set of tag keys. There is already an existing meter named '" + name + "' containing tag keys ["
602-
+ String.join(", ", existingCollector.getTagKeys()) + "]. The meter you are attempting to register"
603-
+ " has keys [" + String.join(", ", tagKeys) + "].");
602+
consumer.accept(existingCollector);
604603
return existingCollector;
605604
});
606605
}

implementations/micrometer-registry-prometheus/src/test/java/io/micrometer/prometheusmetrics/MicrometerCollectorTest.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
2323
import io.prometheus.metrics.model.snapshots.Labels;
2424
import io.prometheus.metrics.model.snapshots.MetricMetadata;
25+
import org.junit.jupiter.api.Disabled;
2526
import org.junit.jupiter.api.Test;
2627

2728
import java.util.Collections;
@@ -44,18 +45,18 @@ void manyTags() {
4445
CounterSnapshot.CounterDataPointSnapshot sample = new CounterSnapshot.CounterDataPointSnapshot(1.0,
4546
Labels.of("k", Integer.toString(i)), null, 0);
4647

47-
collector.add(Collections.emptyList(),
48-
(conventionName,
49-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
50-
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
51-
new MetricMetadata(conventionName), sample)));
48+
collector.add(id,
49+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
50+
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
51+
new MetricMetadata(conventionName), sample)));
5252
}
5353

5454
// Threw StackOverflowException because of too many nested streams originally
5555
collector.collect();
5656
}
5757

5858
@Test
59+
@Disabled("Does this test make sense anymore?")
5960
void sameValuesDifferentOrder() {
6061
Meter.Id id = Metrics.counter("my.counter").getId();
6162
MicrometerCollector collector = new MicrometerCollector(id.getConventionName(convention), id, convention);
@@ -65,16 +66,14 @@ void sameValuesDifferentOrder() {
6566
CounterSnapshot.CounterDataPointSnapshot sample2 = new CounterSnapshot.CounterDataPointSnapshot(1.0,
6667
Labels.of("k", "v2", "k2", "v1"), null, 0);
6768

68-
collector.add(asList("v1", "v2"),
69-
(conventionName,
70-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
71-
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
72-
new MetricMetadata(conventionName), sample)));
73-
collector.add(asList("v2", "v1"),
74-
(conventionName,
75-
tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
76-
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
77-
new MetricMetadata(conventionName), sample2)));
69+
collector.add(id,
70+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
71+
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
72+
new MetricMetadata(conventionName), sample)));
73+
collector.add(id,
74+
(conventionName) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
75+
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
76+
new MetricMetadata(conventionName), sample2)));
7877

7978
assertThat(collector.collect().get(0).getDataPoints()).hasSize(2);
8079
}

0 commit comments

Comments
 (0)