Skip to content

Commit edaf26a

Browse files
committed
export of Dropwizard metrics should use original name in help message
Dropwizard metric name can contain characters which are not allowed in Prometheus metrics name. For example `my.application.namedTimer1`. This name is then sanitized to `my_application_namedTimer1`. The change is that help message should provide original metric name: `Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=com.codahale.metrics.Timer)` instead of `Generated from Dropwizard metric import (metric=my_application_namedTimer1, type=com.codahale.metrics.Timer)` Metric name in help message was not correct.
1 parent 5ca4a6a commit edaf26a

2 files changed

Lines changed: 85 additions & 25 deletions

File tree

simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import java.util.logging.Logger;
1212

1313
/**
14-
* Collect dropwizard metrics from a MetricRegistry.
14+
* Collect Dropwizard metrics from a MetricRegistry.
1515
*/
1616
public class DropwizardExports extends io.prometheus.client.Collector {
1717
private MetricRegistry registry;
@@ -27,21 +27,23 @@ public DropwizardExports(MetricRegistry registry) {
2727
/**
2828
* Export counter as Prometheus <a href="https://prometheus.io/docs/concepts/metric_types/#gauge">Gauge</a>.
2929
*/
30-
List<MetricFamilySamples> fromCounter(String name, Counter counter) {
30+
List<MetricFamilySamples> fromCounter(String dropwizardName, Counter counter) {
31+
String name = sanitizeMetricName(dropwizardName);
3132
MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample(name, new ArrayList<String>(), new ArrayList<String>(),
3233
new Long(counter.getCount()).doubleValue());
33-
return Arrays.asList(new MetricFamilySamples(name, Type.GAUGE, getHelpMessage(name, counter), Arrays.asList(sample)));
34+
return Arrays.asList(new MetricFamilySamples(name, Type.GAUGE, getHelpMessage(dropwizardName, counter), Arrays.asList(sample)));
3435
}
3536

3637
private static String getHelpMessage(String metricName, Metric metric){
37-
return String.format("Generated from dropwizard metric import (metric=%s, type=%s)",
38+
return String.format("Generated from Dropwizard metric import (metric=%s, type=%s)",
3839
metricName, metric.getClass().getName());
3940
}
4041

4142
/**
4243
* Export gauge as a prometheus gauge.
4344
*/
44-
List<MetricFamilySamples> fromGauge(String name, Gauge gauge) {
45+
List<MetricFamilySamples> fromGauge(String dropwizardName, Gauge gauge) {
46+
String name = sanitizeMetricName(dropwizardName);
4547
Object obj = gauge.getValue();
4648
double value;
4749
if (obj instanceof Number) {
@@ -55,19 +57,20 @@ List<MetricFamilySamples> fromGauge(String name, Gauge gauge) {
5557
}
5658
MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample(name,
5759
new ArrayList<String>(), new ArrayList<String>(), value);
58-
return Arrays.asList(new MetricFamilySamples(name, Type.GAUGE, getHelpMessage(name, gauge), Arrays.asList(sample)));
60+
return Arrays.asList(new MetricFamilySamples(name, Type.GAUGE, getHelpMessage(dropwizardName, gauge), Arrays.asList(sample)));
5961
}
6062

6163
/**
6264
* Export a histogram snapshot as a prometheus SUMMARY.
6365
*
64-
* @param name metric name.
66+
* @param dropwizardName metric name.
6567
* @param snapshot the histogram snapshot.
6668
* @param count the total sample count for this snapshot.
6769
* @param factor a factor to apply to histogram values.
6870
*
6971
*/
70-
List<MetricFamilySamples> fromSnapshotAndCount(String name, Snapshot snapshot, long count, double factor, String helpMessage) {
72+
List<MetricFamilySamples> fromSnapshotAndCount(String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) {
73+
String name = sanitizeMetricName(dropwizardName);
7174
List<MetricFamilySamples.Sample> samples = Arrays.asList(
7275
new MetricFamilySamples.Sample(name, Arrays.asList("quantile"), Arrays.asList("0.5"), snapshot.getMedian() * factor),
7376
new MetricFamilySamples.Sample(name, Arrays.asList("quantile"), Arrays.asList("0.75"), snapshot.get75thPercentile() * factor),
@@ -85,25 +88,26 @@ List<MetricFamilySamples> fromSnapshotAndCount(String name, Snapshot snapshot, l
8588
/**
8689
* Convert histogram snapshot.
8790
*/
88-
List<MetricFamilySamples> fromHistogram(String name, Histogram histogram) {
89-
return fromSnapshotAndCount(name, histogram.getSnapshot(), histogram.getCount(), 1.0,
90-
getHelpMessage(name, histogram));
91+
List<MetricFamilySamples> fromHistogram(String dropwizardName, Histogram histogram) {
92+
return fromSnapshotAndCount(dropwizardName, histogram.getSnapshot(), histogram.getCount(), 1.0,
93+
getHelpMessage(dropwizardName, histogram));
9194
}
9295

9396
/**
94-
* Export dropwizard Timer as a histogram. Use TIME_UNIT as time unit.
97+
* Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit.
9598
*/
96-
List<MetricFamilySamples> fromTimer(String name, Timer timer) {
97-
return fromSnapshotAndCount(name, timer.getSnapshot(), timer.getCount(),
98-
1.0D / TimeUnit.SECONDS.toNanos(1L), getHelpMessage(name, timer));
99+
List<MetricFamilySamples> fromTimer(String dropwizardName, Timer timer) {
100+
return fromSnapshotAndCount(dropwizardName, timer.getSnapshot(), timer.getCount(),
101+
1.0D / TimeUnit.SECONDS.toNanos(1L), getHelpMessage(dropwizardName, timer));
99102
}
100103

101104
/**
102105
* Export a Meter as as prometheus COUNTER.
103106
*/
104-
List<MetricFamilySamples> fromMeter(String name, Meter meter) {
107+
List<MetricFamilySamples> fromMeter(String dropwizardName, Meter meter) {
108+
String name = sanitizeMetricName(dropwizardName);
105109
return Arrays.asList(
106-
new MetricFamilySamples(name + "_total", Type.COUNTER, getHelpMessage(name, meter),
110+
new MetricFamilySamples(name + "_total", Type.COUNTER, getHelpMessage(dropwizardName, meter),
107111
Arrays.asList(new MetricFamilySamples.Sample(name + "_total",
108112
new ArrayList<String>(),
109113
new ArrayList<String>(),
@@ -115,30 +119,30 @@ List<MetricFamilySamples> fromMeter(String name, Meter meter) {
115119
/**
116120
* Replace all unsupported chars with '_'.
117121
*
118-
* @param name metric name.
122+
* @param dropwizardName original metric name.
119123
* @return the sanitized metric name.
120124
*/
121-
public static String sanitizeMetricName(String name){
122-
return name.replaceAll("[^a-zA-Z0-9:_]", "_");
125+
public static String sanitizeMetricName(String dropwizardName){
126+
return dropwizardName.replaceAll("[^a-zA-Z0-9:_]", "_");
123127
}
124128

125129
@Override
126130
public List<MetricFamilySamples> collect() {
127131
ArrayList<MetricFamilySamples> mfSamples = new ArrayList<MetricFamilySamples>();
128132
for (SortedMap.Entry<String, Gauge> entry : registry.getGauges().entrySet()) {
129-
mfSamples.addAll(fromGauge(sanitizeMetricName(entry.getKey()), entry.getValue()));
133+
mfSamples.addAll(fromGauge(entry.getKey(), entry.getValue()));
130134
}
131135
for (SortedMap.Entry<String, Counter> entry : registry.getCounters().entrySet()) {
132-
mfSamples.addAll(fromCounter(sanitizeMetricName(entry.getKey()), entry.getValue()));
136+
mfSamples.addAll(fromCounter(entry.getKey(), entry.getValue()));
133137
}
134138
for (SortedMap.Entry<String, Histogram> entry : registry.getHistograms().entrySet()) {
135-
mfSamples.addAll(fromHistogram(sanitizeMetricName(entry.getKey()), entry.getValue()));
139+
mfSamples.addAll(fromHistogram(entry.getKey(), entry.getValue()));
136140
}
137141
for (SortedMap.Entry<String, Timer> entry : registry.getTimers().entrySet()) {
138-
mfSamples.addAll(fromTimer(sanitizeMetricName(entry.getKey()), entry.getValue()));
142+
mfSamples.addAll(fromTimer(entry.getKey(), entry.getValue()));
139143
}
140144
for (SortedMap.Entry<String, Meter> entry : registry.getMeters().entrySet()) {
141-
mfSamples.addAll(fromMeter(sanitizeMetricName(entry.getKey()), entry.getValue()));
145+
mfSamples.addAll(fromMeter(entry.getKey(), entry.getValue()));
142146
}
143147
return mfSamples;
144148
}

simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@
22

33

44
import com.codahale.metrics.*;
5+
import io.prometheus.client.Collector;
56
import io.prometheus.client.CollectorRegistry;
67
import org.junit.Before;
78
import org.junit.Test;
89

910
import java.io.IOException;
1011
import java.util.Arrays;
12+
import java.util.Enumeration;
13+
import java.util.HashMap;
14+
import java.util.Map;
1115

16+
import static org.hamcrest.CoreMatchers.is;
1217
import static org.junit.Assert.assertEquals;
1318
import static org.junit.Assert.assertNotEquals;
19+
import static org.junit.Assert.assertThat;
1420
import static org.junit.Assert.assertTrue;
1521

1622
public class DropwizardExportsTest {
@@ -142,4 +148,54 @@ public void testTimer() throws IOException, InterruptedException {
142148
public void testSanitizeMetricName() {
143149
assertEquals("Foo_Bar_metric_mame", DropwizardExports.sanitizeMetricName("Foo.Bar-metric,mame"));
144150
}
151+
152+
@Test
153+
public void testThatMetricHelpUsesOriginalDropwizardName() {
154+
metricRegistry.timer("my.application.namedTimer1");
155+
metricRegistry.counter("my.application.namedCounter1");
156+
metricRegistry.meter("my.application.namedMeter1");
157+
metricRegistry.histogram("my.application.namedHistogram1");
158+
metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge());
159+
160+
Enumeration<Collector.MetricFamilySamples> metricFamilySamples = registry.metricFamilySamples();
161+
162+
163+
Map<String, Collector.MetricFamilySamples> elements = new HashMap<String, Collector.MetricFamilySamples>();
164+
165+
while (metricFamilySamples.hasMoreElements()) {
166+
Collector.MetricFamilySamples element = metricFamilySamples.nextElement();
167+
elements.put(element.name, element);
168+
}
169+
assertEquals(5, elements.size());
170+
171+
assertTrue(elements.keySet().contains("my_application_namedTimer1"));
172+
assertTrue(elements.keySet().contains("my_application_namedCounter1"));
173+
assertTrue(elements.keySet().contains("my_application_namedMeter1_total"));
174+
assertTrue(elements.keySet().contains("my_application_namedHistogram1"));
175+
assertTrue(elements.keySet().contains("my_application_namedGauge1"));
176+
177+
assertThat(elements.get("my_application_namedTimer1").help,
178+
is("Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=com.codahale.metrics.Timer)"));
179+
180+
assertThat(elements.get("my_application_namedCounter1").help,
181+
is("Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=com.codahale.metrics.Counter)"));
182+
183+
assertThat(elements.get("my_application_namedMeter1_total").help,
184+
is("Generated from Dropwizard metric import (metric=my.application.namedMeter1, type=com.codahale.metrics.Meter)"));
185+
186+
assertThat(elements.get("my_application_namedHistogram1").help,
187+
is("Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=com.codahale.metrics.Histogram)"));
188+
189+
assertThat(elements.get("my_application_namedGauge1").help,
190+
is("Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.client.dropwizard.DropwizardExportsTest$ExampleDoubleGauge)"));
191+
192+
}
193+
194+
195+
private static class ExampleDoubleGauge implements Gauge<Double> {
196+
@Override
197+
public Double getValue() {
198+
return 0.0;
199+
}
200+
}
145201
}

0 commit comments

Comments
 (0)