Skip to content

Commit c07a50b

Browse files
AleksandrKolosovvancexu
authored andcommitted
Fix prometheus reporting issue (#507)
MetricsType.ACTIVITY_SCHEDULED_TO_START_LATENCY is reported twice with different set of tags. It causes prometheus to fail with an IllegalArgumentException: "Prometheus requires that all meters with the same name have the same set of tag keys." Made all metrics to be reported with the same set of tags. Improved reporter to track gauges as well.
1 parent eeb8f9c commit c07a50b

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

src/main/java/com/uber/cadence/reporter/CadenceClientStatsReporter.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
package com.uber.cadence.reporter;
1919

20+
import com.google.common.base.Preconditions;
21+
import com.google.common.base.Strings;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.common.util.concurrent.AtomicDouble;
24+
import com.uber.cadence.internal.metrics.MetricsTag;
2025
import com.uber.m3.tally.Buckets;
2126
import com.uber.m3.tally.Capabilities;
2227
import com.uber.m3.tally.CapableOf;
@@ -25,11 +30,13 @@
2530
import io.micrometer.core.instrument.Metrics;
2631
import io.micrometer.core.instrument.Tag;
2732
import java.util.Map;
33+
import java.util.concurrent.ConcurrentHashMap;
2834
import java.util.concurrent.TimeUnit;
29-
import java.util.stream.Collectors;
3035

3136
public class CadenceClientStatsReporter implements StatsReporter {
3237

38+
private final Map<String, AtomicDouble> gauges = new ConcurrentHashMap<>();
39+
3340
@Override
3441
public Capabilities capabilities() {
3542
return CapableOf.REPORTING;
@@ -52,7 +59,12 @@ public void reportCounter(String name, Map<String, String> tags, long value) {
5259

5360
@Override
5461
public void reportGauge(String name, Map<String, String> tags, double value) {
55-
// NOOP
62+
AtomicDouble gauge = gauges.computeIfAbsent(name, metricName -> {
63+
AtomicDouble result = Metrics.gauge(name, getTags(tags), new AtomicDouble());
64+
Preconditions.checkNotNull(result, "Metrics.gauge should not return null ever");
65+
return result;
66+
});
67+
gauge.set(value);
5668
}
5769

5870
@Override
@@ -83,9 +95,11 @@ public void reportHistogramDurationSamples(
8395
}
8496

8597
private Iterable<Tag> getTags(Map<String, String> tags) {
86-
return tags.entrySet()
87-
.stream()
88-
.map(entry -> Tag.of(entry.getKey(), entry.getValue()))
89-
.collect(Collectors.toList());
98+
return ImmutableList.of(
99+
Tag.of(MetricsTag.ACTIVITY_TYPE, Strings.nullToEmpty(tags.get(MetricsTag.ACTIVITY_TYPE))),
100+
Tag.of(MetricsTag.DOMAIN, Strings.nullToEmpty(tags.get(MetricsTag.DOMAIN))),
101+
Tag.of(MetricsTag.TASK_LIST, Strings.nullToEmpty(tags.get(MetricsTag.TASK_LIST))),
102+
Tag.of(MetricsTag.WORKFLOW_TYPE, Strings.nullToEmpty(tags.get(MetricsTag.WORKFLOW_TYPE)))
103+
);
90104
}
91105
}

src/test/java/com/uber/cadence/reporter/CadenceClientStatsReporterTest.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121

22+
import com.uber.cadence.internal.metrics.MetricsTag;
2223
import com.uber.m3.tally.CapableOf;
2324
import com.uber.m3.util.Duration;
2425
import com.uber.m3.util.ImmutableMap;
2526
import io.micrometer.core.instrument.Metrics;
2627
import io.micrometer.core.instrument.Tag;
2728
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
2829
import java.util.Arrays;
30+
import java.util.List;
2931
import java.util.Map;
3032
import java.util.concurrent.TimeUnit;
3133
import org.junit.After;
@@ -36,9 +38,15 @@ public class CadenceClientStatsReporterTest {
3638

3739
private static final String DEFAULT_REPORT_NAME = "cadence_workflow_start";
3840
private static final Map<String, String> DEFAULT_REPORT_TAGS =
39-
ImmutableMap.of("Domain", "domain_name", "TaskList", "task_list");
41+
ImmutableMap.of(MetricsTag.DOMAIN, "domain_name", MetricsTag.TASK_LIST, "task_list");
4042
private static final long DEFAULT_COUNT = 10;
43+
private static final double DEFAULT_VALUE = 1.0;
4144
private static final Duration DEFAULT_DURATION = Duration.ofSeconds(10);
45+
private static final List<Tag> EXPECTED_REPORT_TAGS = Arrays.asList(
46+
Tag.of(MetricsTag.ACTIVITY_TYPE, ""),
47+
Tag.of(MetricsTag.DOMAIN, "domain_name"),
48+
Tag.of(MetricsTag.TASK_LIST, "task_list"),
49+
Tag.of(MetricsTag.WORKFLOW_TYPE, ""));
4250

4351
private CadenceClientStatsReporter cadenceClientStatsReporter = new CadenceClientStatsReporter();
4452

@@ -61,8 +69,7 @@ public void testReporterCapabilitiesShouldReturnReporting() {
6169
public void testCounterShouldCallMetricRegistryForMonitoredCounterCadenceAction() {
6270
callDefaultCounter();
6371

64-
assertEquals(
65-
Arrays.asList(Tag.of("Domain", "domain_name"), Tag.of("TaskList", "task_list")),
72+
assertEquals(EXPECTED_REPORT_TAGS,
6673
Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).counter().getId().getTags());
6774
assertEquals(10, Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).counter().count(), 0);
6875
}
@@ -71,13 +78,21 @@ public void testCounterShouldCallMetricRegistryForMonitoredCounterCadenceAction(
7178
public void testTimerShouldCallMetricRegistryForMonitoredCounterCadenceAction() {
7279
callDefaultTimer();
7380

74-
assertEquals(
75-
Arrays.asList(Tag.of("Domain", "domain_name"), Tag.of("TaskList", "task_list")),
81+
assertEquals(EXPECTED_REPORT_TAGS,
7682
Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).timer().getId().getTags());
7783
assertEquals(
7884
10, Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).timer().totalTime(TimeUnit.SECONDS), 0);
7985
}
8086

87+
@Test
88+
public void testGaugeShouldCallMetricRegistryForMonitoredGaugeCadenceAction() {
89+
callDefaultGauge();
90+
91+
assertEquals(EXPECTED_REPORT_TAGS,
92+
Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).gauge().getId().getTags());
93+
assertEquals(1.0, Metrics.globalRegistry.get(DEFAULT_REPORT_NAME).gauge().value(), 0);
94+
}
95+
8196
private void callDefaultCounter() {
8297
cadenceClientStatsReporter.reportCounter(
8398
DEFAULT_REPORT_NAME, DEFAULT_REPORT_TAGS, DEFAULT_COUNT);
@@ -87,4 +102,8 @@ private void callDefaultTimer() {
87102
cadenceClientStatsReporter.reportTimer(
88103
DEFAULT_REPORT_NAME, DEFAULT_REPORT_TAGS, DEFAULT_DURATION);
89104
}
105+
106+
private void callDefaultGauge() {
107+
cadenceClientStatsReporter.reportGauge(DEFAULT_REPORT_NAME, DEFAULT_REPORT_TAGS, DEFAULT_VALUE);
108+
}
90109
}

0 commit comments

Comments
 (0)