0
# Counter Metrics
1
2
Counter metrics track counts and totals that only increase (except on resets). Use counters for tracking requests processed, errors occurred, bytes transferred, or any other monotonically increasing values.
3
4
## Capabilities
5
6
### Counter Creation
7
8
Create counter metrics using the builder pattern with required name and help text.
9
10
```java { .api }
11
/**
12
* Create a new Counter builder
13
* @return Builder instance for configuration
14
*/
15
public static Counter.Builder build();
16
17
/**
18
* Create a new Counter builder with required fields
19
* @param name The metric name (will have _total suffix added)
20
* @param help The help text describing the metric
21
* @return Builder instance for configuration
22
*/
23
public static Counter.Builder build(String name, String help);
24
```
25
26
**Usage Example:**
27
28
```java
29
import io.prometheus.client.Counter;
30
31
// Basic counter
32
Counter requestsTotal = Counter.build()
33
.name("requests_total")
34
.help("Total number of requests")
35
.register();
36
37
// Counter with labels
38
Counter httpRequestsTotal = Counter.build()
39
.name("http_requests_total")
40
.help("Total HTTP requests")
41
.labelNames("method", "status")
42
.register();
43
```
44
45
### Counter Builder Configuration
46
47
Configure counter metrics with labels, namespace, and exemplar support.
48
49
```java { .api }
50
public static class Builder extends SimpleCollector.Builder<Builder, Counter> {
51
/**
52
* Enable exemplar support with default sampler
53
* @return Builder for method chaining
54
*/
55
public Builder withExemplars();
56
57
/**
58
* Disable exemplar support
59
* @return Builder for method chaining
60
*/
61
public Builder withoutExemplars();
62
63
/**
64
* Configure custom exemplar sampler
65
* @param exemplarSampler Custom sampler implementation
66
* @return Builder for method chaining
67
*/
68
public Builder withExemplarSampler(CounterExemplarSampler exemplarSampler);
69
}
70
```
71
72
### Counter Operations
73
74
Increment counter values with optional exemplar support for trace correlation.
75
76
```java { .api }
77
/**
78
* Increment counter by 1
79
*/
80
public void inc();
81
82
/**
83
* Increment counter by specified amount
84
* @param amt Amount to increment (must be non-negative)
85
* @throws IllegalArgumentException if amt is negative
86
*/
87
public void inc(double amt);
88
89
/**
90
* Increment by 1 with exemplar for trace correlation
91
* @param exemplarLabels Trace labels as name/value pairs
92
*/
93
public void incWithExemplar(String... exemplarLabels);
94
95
/**
96
* Increment by amount with exemplar for trace correlation
97
* @param amt Amount to increment (must be non-negative)
98
* @param exemplarLabels Trace labels as name/value pairs
99
* @throws IllegalArgumentException if amt is negative
100
*/
101
public void incWithExemplar(double amt, String... exemplarLabels);
102
103
/**
104
* Increment with exemplar using Map for labels
105
* @param amt Amount to increment
106
* @param exemplarLabels Map of label names to values
107
*/
108
public void incWithExemplar(double amt, Map<String, String> exemplarLabels);
109
110
/**
111
* Increment by 1 with exemplar using Map for labels
112
* @param exemplarLabels Map of label names to values
113
*/
114
public void incWithExemplar(Map<String, String> exemplarLabels);
115
116
/**
117
* Get current counter value
118
* @return Current counter value
119
*/
120
public double get();
121
122
/**
123
* Collect metric samples from this counter
124
* @return List of MetricFamilySamples
125
*/
126
public List<MetricFamilySamples> collect();
127
128
/**
129
* Describe this counter metric
130
* @return List of MetricFamilySamples for description
131
*/
132
public List<MetricFamilySamples> describe();
133
```
134
135
**Usage Examples:**
136
137
```java
138
// Basic increment operations
139
requestsTotal.inc();
140
requestsTotal.inc(5.0);
141
142
// Labeled counters
143
httpRequestsTotal.labels("GET", "200").inc();
144
httpRequestsTotal.labels("POST", "404").inc(2);
145
146
// With exemplars for tracing
147
requestsTotal.incWithExemplar("trace_id", "abc123");
148
requestsTotal.incWithExemplar(3.0, "trace_id", "def456", "span_id", "789");
149
150
// Using Map for exemplar labels
151
Map<String, String> traceLabels = new HashMap<>();
152
traceLabels.put("trace_id", "xyz789");
153
requestsTotal.incWithExemplar(1.0, traceLabels);
154
```
155
156
### Labeled Counter Operations
157
158
Work with multi-dimensional counters using label values to create distinct time series.
159
160
```java { .api }
161
/**
162
* Get counter child for specific label values
163
* @param labelValues Values for each label name (must match count)
164
* @return Counter.Child instance for the label combination
165
* @throws IllegalArgumentException if wrong number of labels
166
*/
167
public Counter.Child labels(String... labelValues);
168
169
/**
170
* Remove counter child for specific label values
171
* @param labelValues Values identifying the child to remove
172
*/
173
public void remove(String... labelValues);
174
175
/**
176
* Remove all counter children
177
*/
178
public void clear();
179
```
180
181
### Counter Child Operations
182
183
Counter.Child provides the same increment operations for labeled instances.
184
185
```java { .api }
186
public static class Child {
187
/**
188
* Default constructor
189
*/
190
public Child();
191
192
/**
193
* Constructor with exemplar configuration
194
* @param exemplarsEnabled Whether exemplars are enabled for this child
195
* @param exemplarSampler Custom exemplar sampler or null for default
196
*/
197
public Child(Boolean exemplarsEnabled, CounterExemplarSampler exemplarSampler);
198
199
/** Increment child counter by 1 */
200
public void inc();
201
202
/** Increment child counter by amount */
203
public void inc(double amt);
204
205
/** Increment with exemplar support */
206
public void incWithExemplar(String... exemplarLabels);
207
public void incWithExemplar(double amt, String... exemplarLabels);
208
public void incWithExemplar(double amt, Map<String, String> exemplarLabels);
209
public void incWithExemplar(Map<String, String> exemplarLabels);
210
211
/** Get current child counter value */
212
public double get();
213
214
/** Get creation timestamp in milliseconds */
215
public long created();
216
}
217
```
218
219
**Usage Example:**
220
221
```java
222
// Working with labeled counters
223
Counter.Child getRequests = httpRequestsTotal.labels("GET", "200");
224
getRequests.inc();
225
getRequests.inc(3.0);
226
227
// Get current values
228
double totalRequests = requestsTotal.get();
229
double getRequestCount = getRequests.get();
230
231
// Remove specific label combination
232
httpRequestsTotal.remove("GET", "404");
233
234
// Clear all children
235
httpRequestsTotal.clear();
236
```
237
238
## Important Notes
239
240
### Counter Naming Convention
241
242
Counters automatically handle the `_total` suffix:
243
- If you specify `requests_total` as the name, it becomes `requests` internally
244
- When exported, it appears as `requests_total` for Prometheus compatibility
245
- Always use meaningful names that indicate what is being counted
246
247
### Thread Safety
248
249
All counter operations are thread-safe and designed for high-concurrency environments:
250
251
```java
252
// Safe to call from multiple threads simultaneously
253
Counter.Builder.create().name("concurrent_ops").help("Ops").register();
254
Counter concurrentCounter = Counter.build().name("thread_safe").help("Example").register();
255
256
// Multiple threads can safely increment
257
concurrentCounter.inc(); // Thread-safe
258
concurrentCounter.labels("method", "POST").inc(); // Thread-safe
259
```
260
261
### Error Handling
262
263
Counters validate input and throw appropriate exceptions:
264
265
```java
266
try {
267
counter.inc(-1.0); // Throws IllegalArgumentException
268
} catch (IllegalArgumentException e) {
269
// Handle negative increment attempt
270
}
271
272
try {
273
counter.labels("too", "many", "labels"); // Throws if label count mismatch
274
} catch (IllegalArgumentException e) {
275
// Handle incorrect label count
276
}
277
```