forked from prometheus/client_java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCounter.java
More file actions
173 lines (161 loc) · 4.6 KB
/
Counter.java
File metadata and controls
173 lines (161 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package io.prometheus.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Counter metric, to track counts of events or running totals.
* <p>
* Example of Counters include:
* <ul>
* <li>Number of requests processed</li>
* <li>Number of items that were inserted into a queue</li>
* <li>Total amount of data a system has processed</li>
* </ul>
*
* Counters can only go up (and be reset), if your use case can go down you should use a {@link Gauge} instead.
* Use the <code>rate()</code> function in Prometheus to calculate the rate of increase of a Counter.
* By convention, the names of Counters are suffixed by <code>_total</code>.
*
* <p>
* An example Counter:
* <pre>
* {@code
* class YourClass {
* static final Counter requests = Counter.build()
* .name("requests_total").help("Total requests.").register();
* static final Counter failedRequests = Counter.build()
* .name("requests_failed_total").help("Total failed requests.").register();
*
* void processRequest() {
* requests.inc();
* try {
* // Your code here.
* } catch (Exception e) {
* failedRequests.inc();
* throw e;
* }
* }
* }
* }
* </pre>
*
* <p>
* You can also use labels to track different types of metric:
* <pre>
* {@code
* class YourClass {
* static final Counter requests = Counter.build()
* .name("requests_total").help("Total requests.")
* .labelNames("method").register();
*
* void processGetRequest() {
* requests.labels("get").inc();
* // Your code here.
* }
* void processPostRequest() {
* requests.labels("post").inc();
* // Your code here.
* }
* }
* }
* </pre>
* These can be aggregated and processed together much more easily in the Prometheus
* server than individual metrics for each labelset.
*/
public class Counter extends SimpleCollector<Counter.Child> implements Collector.Describable {
Counter(Builder b) {
super(b);
}
public static class Builder extends SimpleCollector.Builder<Builder, Counter> {
@Override
public Counter create() {
return new Counter(this);
}
}
/**
* Return a Builder to allow configuration of a new Counter. Ensures required fields are provided.
*
* @param name The name of the metric
* @param help The help string of the metric
*/
public static Builder build(String name, String help) {
return new Builder().name(name).help(help);
}
/**
* Return a Builder to allow configuration of a new Counter.
*/
public static Builder build() {
return new Builder();
}
@Override
protected Child newChild() {
return new Child();
}
/**
* The value of a single Counter.
* <p>
* <em>Warning:</em> References to a Child become invalid after using
* {@link SimpleCollector#remove} or {@link SimpleCollector#clear},
*/
public static class Child {
private final DoubleAdder value = new DoubleAdder();
/**
* Increment the counter by 1.
*/
public void inc() {
inc(1.0);
}
/**
* Increment the counter by the given amount.
* @throws IllegalArgumentException If amt is negative.
*/
public void inc(double amt) {
if (amt < 0.0) {
throw new IllegalArgumentException("Amount to increment must be non-negative.");
}
value.add(amt);
}
/**
* Get the value of the counter.
*/
public double get() {
return value.sum();
}
}
// Convenience methods.
/**
* Increment the counter with no labels by 1.
*/
public void inc() {
inc(1.0);
}
/**
* Increment the counter with no labels by the given amount.
* @throws IllegalArgumentException If amt is negative.
*/
public void inc(double amt) {
noLabelsChild.inc(amt);
}
/**
* Get the value of the counter.
*/
public double get() {
return noLabelsChild.get();
}
@Override
public List<MetricFamilySamples> collect() {
final Map.Entry<List<String>, Child>[] children = children();
List<MetricFamilySamples.Sample> samples = new ArrayList<MetricFamilySamples.Sample>(children.length);
for(Map.Entry<List<String>, Child> c : children) {
if (c != null) {
samples.add(new MetricFamilySamples.Sample(fullname, labelNames, c.getKey(), c.getValue().get()));
}
}
return familySamplesList(Type.COUNTER, samples);
}
@Override
public List<MetricFamilySamples> describe() {
return Collections.<MetricFamilySamples>singletonList(new CounterMetricFamily(fullname, help, labelNames));
}
}