Skip to content

Commit 5c66e58

Browse files
authored
Merge pull request #615 from prometheus/om
Convert client_java to OpenMetrics
2 parents f09c46b + cf018d1 commit 5c66e58

File tree

33 files changed

+1372
-75
lines changed

33 files changed

+1372
-75
lines changed

simpleclient/src/main/java/io/prometheus/client/Collector.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
package io.prometheus.client;
33

4+
import java.util.ArrayList;
45
import java.util.List;
56
import java.util.regex.Pattern;
67

@@ -19,27 +20,58 @@ public abstract class Collector {
1920
*/
2021
public abstract List<MetricFamilySamples> collect();
2122
public enum Type {
23+
UNKNOWN, // This is untyped in Prometheus text format.
2224
COUNTER,
2325
GAUGE,
24-
SUMMARY,
26+
STATE_SET,
27+
INFO,
2528
HISTOGRAM,
26-
UNTYPED,
29+
GAUGE_HISTOGRAM,
30+
SUMMARY,
2731
}
2832

2933
/**
3034
* A metric, and all of its samples.
3135
*/
3236
static public class MetricFamilySamples {
3337
public final String name;
38+
public final String unit;
3439
public final Type type;
3540
public final String help;
3641
public final List<Sample> samples;
3742

38-
public MetricFamilySamples(String name, Type type, String help, List<Sample> samples) {
43+
public MetricFamilySamples(String name, String unit, Type type, String help, List<Sample> samples) {
44+
if (!unit.isEmpty() && !name.endsWith("_" + unit)) {
45+
throw new IllegalArgumentException("Metric's unit is not the suffix of the metric name: " + name);
46+
}
47+
if ((type == Type.INFO || type == Type.STATE_SET) && !unit.isEmpty()) {
48+
throw new IllegalArgumentException("Metric is of a type that cannot have a unit: " + name);
49+
}
50+
List<Sample> mungedSamples = samples;
51+
// Deal with _total from pre-OM automatically.
52+
if (type == Type.COUNTER) {
53+
if (name.endsWith("_total")) {
54+
name = name.substring(0, name.length() - 6);
55+
}
56+
String withTotal = name + "_total";
57+
mungedSamples = new ArrayList<Sample>(samples.size());
58+
for (Sample s: samples) {
59+
String n = s.name;
60+
if (name.equals(n)) {
61+
n = withTotal;
62+
}
63+
mungedSamples.add(new Sample(n, s.labelNames, s.labelValues, s.value, s.timestampMs));
64+
}
65+
}
3966
this.name = name;
67+
this.unit = unit;
4068
this.type = type;
4169
this.help = help;
42-
this.samples = samples;
70+
this.samples = mungedSamples;
71+
}
72+
73+
public MetricFamilySamples(String name, Type type, String help, List<Sample> samples) {
74+
this(name, "", type, help, samples);
4375
}
4476

4577
@Override
@@ -49,14 +81,18 @@ public boolean equals(Object obj) {
4981
}
5082
MetricFamilySamples other = (MetricFamilySamples) obj;
5183

52-
return other.name.equals(name) && other.type.equals(type)
53-
&& other.help.equals(help) && other.samples.equals(samples) ;
84+
return other.name.equals(name)
85+
&& other.unit.equals(unit)
86+
&& other.type.equals(type)
87+
&& other.help.equals(help)
88+
&& other.samples.equals(samples);
5489
}
5590

5691
@Override
5792
public int hashCode() {
5893
int hash = 1;
5994
hash = 37 * hash + name.hashCode();
95+
hash = 37 * hash + unit.hashCode();
6096
hash = 37 * hash + type.hashCode();
6197
hash = 37 * hash + help.hashCode();
6298
hash = 37 * hash + samples.hashCode();
@@ -65,7 +101,7 @@ public int hashCode() {
65101

66102
@Override
67103
public String toString() {
68-
return "Name: " + name + " Type: " + type + " Help: " + help +
104+
return "Name: " + name + " Unit:" + unit + " Type: " + type + " Help: " + help +
69105
" Samples: " + samples;
70106
}
71107

simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,32 @@ private List<String> collectorNames(Collector m) {
105105
List<String> names = new ArrayList<String>();
106106
for (Collector.MetricFamilySamples family : mfs) {
107107
switch (family.type) {
108+
case COUNTER:
109+
names.add(family.name + "_total");
110+
names.add(family.name + "_created");
111+
names.add(family.name);
112+
break;
108113
case SUMMARY:
109114
names.add(family.name + "_count");
110115
names.add(family.name + "_sum");
116+
names.add(family.name + "_created");
111117
names.add(family.name);
112118
break;
113119
case HISTOGRAM:
114120
names.add(family.name + "_count");
115121
names.add(family.name + "_sum");
116122
names.add(family.name + "_bucket");
123+
names.add(family.name + "_created");
124+
names.add(family.name);
125+
break;
126+
case GAUGE_HISTOGRAM:
127+
names.add(family.name + "_gcount");
128+
names.add(family.name + "_gsum");
129+
names.add(family.name + "_bucket");
130+
names.add(family.name);
131+
break;
132+
case INFO:
133+
names.add(family.name + "_info");
117134
names.add(family.name);
118135
break;
119136
default:

simpleclient/src/main/java/io/prometheus/client/Counter.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@
6464
* </pre>
6565
* These can be aggregated and processed together much more easily in the Prometheus
6666
* server than individual metrics for each labelset.
67+
*
68+
* If there is a suffix of <code>_total</code> on the metric name, it will be
69+
* removed. When exposing the time series for counter value, a
70+
* <code>_total</code> suffix will be added. This is for compatibility between
71+
* OpenMetrics and the Prometheus text format, as OpenMetrics requires the
72+
* <code>_total</code> suffix.
6773
*/
6874
public class Counter extends SimpleCollector<Counter.Child> implements Collector.Describable {
6975

@@ -74,6 +80,10 @@ public class Counter extends SimpleCollector<Counter.Child> implements Collector
7480
public static class Builder extends SimpleCollector.Builder<Builder, Counter> {
7581
@Override
7682
public Counter create() {
83+
// Gracefully handle pre-OpenMetrics counters.
84+
if (name.endsWith("_total")) {
85+
name = name.substring(0, name.length() - 6);
86+
}
7787
return new Counter(this);
7888
}
7989
}
@@ -108,6 +118,7 @@ protected Child newChild() {
108118
*/
109119
public static class Child {
110120
private final DoubleAdder value = new DoubleAdder();
121+
private final long created = System.currentTimeMillis();
111122
/**
112123
* Increment the counter by 1.
113124
*/
@@ -130,6 +141,12 @@ public void inc(double amt) {
130141
public double get() {
131142
return value.sum();
132143
}
144+
/**
145+
* Get the created time of the counter in milliseconds.
146+
*/
147+
public long created() {
148+
return created;
149+
}
133150
}
134151

135152
// Convenience methods.
@@ -158,7 +175,8 @@ public double get() {
158175
public List<MetricFamilySamples> collect() {
159176
List<MetricFamilySamples.Sample> samples = new ArrayList<MetricFamilySamples.Sample>(children.size());
160177
for(Map.Entry<List<String>, Child> c: children.entrySet()) {
161-
samples.add(new MetricFamilySamples.Sample(fullname, labelNames, c.getKey(), c.getValue().get()));
178+
samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get()));
179+
samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0));
162180
}
163181
return familySamplesList(Type.COUNTER, samples);
164182
}

simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public CounterMetricFamily(String name, String help, double value) {
3737
labelNames = Collections.emptyList();
3838
samples.add(
3939
new Sample(
40-
name,
40+
this.name + "_total",
4141
labelNames,
4242
Collections.<String>emptyList(),
4343
value));
@@ -52,7 +52,7 @@ public CounterMetricFamily addMetric(List<String> labelValues, double value) {
5252
if (labelValues.size() != labelNames.size()) {
5353
throw new IllegalArgumentException("Incorrect number of labels.");
5454
}
55-
samples.add(new Sample(name, labelNames, labelValues, value));
55+
samples.add(new Sample(name + "_total", labelNames, labelValues, value));
5656
return this;
5757
}
5858
}

0 commit comments

Comments
 (0)