0
# Histogram Metrics
1
2
Histogram metrics track distributions of values like request latencies, response sizes, or processing times by organizing observations into configurable buckets. They provide count, sum, and bucket data for calculating percentiles and distributions.
3
4
## Capabilities
5
6
### Histogram Creation
7
8
Create histogram metrics using the builder pattern with configurable bucket boundaries.
9
10
```java { .api }
11
/**
12
* Create a new Histogram builder with default buckets
13
* @return Builder instance for configuration
14
*/
15
public static Histogram.Builder build();
16
17
/**
18
* Create a new Histogram builder with required fields
19
* @param name The metric name (without _bucket/_count/_sum suffixes)
20
* @param help The help text describing the metric
21
* @return Builder instance for configuration
22
*/
23
public static Histogram.Builder build(String name, String help);
24
```
25
26
**Usage Example:**
27
28
```java
29
import io.prometheus.client.Histogram;
30
31
// Basic histogram with default buckets
32
Histogram requestDuration = Histogram.build()
33
.name("request_duration_seconds")
34
.help("Request duration in seconds")
35
.register();
36
37
// Histogram with custom buckets
38
Histogram responseSizes = Histogram.build()
39
.name("response_size_bytes")
40
.help("HTTP response sizes")
41
.buckets(.01, .05, .1, .25, .5, 1, 2.5, 5, 10)
42
.register();
43
```
44
45
### Histogram Builder Configuration
46
47
Configure histogram bucket boundaries and exemplar support.
48
49
```java { .api }
50
public static class Builder extends SimpleCollector.Builder<Builder, Histogram> {
51
/**
52
* Set custom bucket boundaries
53
* @param buckets Upper bounds for buckets (must be in increasing order)
54
* @return Builder for method chaining
55
* @throws IllegalStateException if buckets not in increasing order
56
*/
57
public Builder buckets(double... buckets);
58
59
/**
60
* Generate linear bucket sequence
61
* @param start First bucket upper bound
62
* @param width Width between buckets
63
* @param count Number of buckets to generate
64
* @return Builder for method chaining
65
*/
66
public Builder linearBuckets(double start, double width, int count);
67
68
/**
69
* Generate exponential bucket sequence
70
* @param start First bucket upper bound
71
* @param factor Multiplication factor between buckets
72
* @param count Number of buckets to generate
73
* @return Builder for method chaining
74
*/
75
public Builder exponentialBuckets(double start, double factor, int count);
76
77
/**
78
* Enable exemplar support with default sampler
79
* @return Builder for method chaining
80
*/
81
public Builder withExemplars();
82
83
/**
84
* Disable exemplar support
85
* @return Builder for method chaining
86
*/
87
public Builder withoutExemplars();
88
89
/**
90
* Configure custom exemplar sampler
91
* @param exemplarSampler Custom sampler implementation
92
* @return Builder for method chaining
93
*/
94
public Builder withExemplarSampler(HistogramExemplarSampler exemplarSampler);
95
}
96
```
97
98
**Usage Examples:**
99
100
```java
101
// Custom bucket configuration
102
Histogram latencyHistogram = Histogram.build()
103
.name("api_latency_seconds")
104
.help("API request latency")
105
.buckets(0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0)
106
.register();
107
108
// Linear buckets: 10, 20, 30, 40, 50 milliseconds
109
Histogram processingTime = Histogram.build()
110
.name("processing_duration_seconds")
111
.help("Processing duration")
112
.linearBuckets(0.01, 0.01, 5)
113
.register();
114
115
// Exponential buckets: 1, 2, 4, 8, 16, 32 seconds
116
Histogram batchSize = Histogram.build()
117
.name("batch_processing_seconds")
118
.help("Batch processing time")
119
.exponentialBuckets(1, 2, 6)
120
.register();
121
```
122
123
### Histogram Observations
124
125
Record values in histogram buckets with optional exemplar support.
126
127
```java { .api }
128
/**
129
* Record an observation in the histogram
130
* @param amt Value to observe (typically >= 0)
131
*/
132
public void observe(double amt);
133
134
/**
135
* Record observation with exemplar for trace correlation
136
* @param amt Value to observe
137
* @param exemplarLabels Trace labels as name/value pairs
138
*/
139
public void observeWithExemplar(double amt, String... exemplarLabels);
140
141
/**
142
* Record observation with exemplar using Map for labels
143
* @param amt Value to observe
144
* @param exemplarLabels Map of label names to values
145
*/
146
public void observeWithExemplar(double amt, Map<String, String> exemplarLabels);
147
```
148
149
**Usage Examples:**
150
151
```java
152
// Basic observations
153
requestDuration.observe(0.123); // 123ms request
154
responseSizes.observe(1024.0); // 1KB response
155
156
// With exemplars for tracing
157
requestDuration.observeWithExemplar(0.456, "trace_id", "abc123");
158
159
Map<String, String> traceInfo = Map.of(
160
"trace_id", "xyz789",
161
"span_id", "span123"
162
);
163
requestDuration.observeWithExemplar(0.789, traceInfo);
164
```
165
166
### Timer Operations
167
168
Use histograms for automatic duration measurement and timing operations.
169
170
```java { .api }
171
/**
172
* Start a timer for duration measurement
173
* @return Timer instance for duration tracking
174
*/
175
public Timer startTimer();
176
177
/**
178
* Time a Runnable execution and observe duration
179
* @param timeable Code to time
180
* @return Duration in seconds
181
*/
182
public double time(Runnable timeable);
183
184
/**
185
* Time a Callable execution and observe duration
186
* @param timeable Code to time
187
* @return Result from callable
188
* @throws RuntimeException if callable throws exception
189
*/
190
public <E> E time(Callable<E> timeable);
191
192
/**
193
* Time execution with exemplar support
194
* @param timeable Code to time
195
* @param exemplarLabels Trace labels for exemplar
196
* @return Duration in seconds
197
*/
198
public double timeWithExemplar(Runnable timeable, String... exemplarLabels);
199
200
/**
201
* Time callable with exemplar support
202
* @param timeable Code to time
203
* @param exemplarLabels Trace labels for exemplar
204
* @return Result from callable
205
*/
206
public <E> E timeWithExemplar(Callable<E> timeable, String... exemplarLabels);
207
```
208
209
### Histogram Timer Class
210
211
Timer provides duration measurement and exemplar support for histogram metrics.
212
213
```java { .api }
214
public static class Timer implements Closeable {
215
/**
216
* Observe elapsed duration since timer start
217
* @return Elapsed duration in seconds
218
*/
219
public double observeDuration();
220
221
/**
222
* Observe duration with exemplar support
223
* @param exemplarLabels Trace labels for exemplar
224
* @return Elapsed duration in seconds
225
*/
226
public double observeDurationWithExemplar(String... exemplarLabels);
227
228
/**
229
* Observe duration with exemplar Map
230
* @param exemplarLabels Map of trace labels
231
* @return Elapsed duration in seconds
232
*/
233
public double observeDurationWithExemplar(Map<String, String> exemplarLabels);
234
235
/**
236
* Equivalent to observeDuration() - implements Closeable
237
*/
238
public void close();
239
}
240
```
241
242
**Usage Examples:**
243
244
```java
245
// Manual timer usage
246
Histogram.Timer timer = requestDuration.startTimer();
247
try {
248
processRequest();
249
} finally {
250
timer.observeDuration();
251
}
252
253
// Try-with-resources timer
254
try (Histogram.Timer timer = requestDuration.startTimer()) {
255
processRequest(); // Automatically observes duration
256
}
257
258
// Lambda timing
259
double duration = requestDuration.time(() -> {
260
processRequest();
261
});
262
263
// Timing with return value
264
String response = requestDuration.time(() -> {
265
return generateResponse();
266
});
267
268
// Timer with exemplars
269
timer.observeDurationWithExemplar("trace_id", "abc123");
270
```
271
272
### Labeled Histogram Operations
273
274
Work with multi-dimensional histograms using label values.
275
276
```java { .api }
277
/**
278
* Get histogram child for specific label values
279
* @param labelValues Values for each label name (must match count)
280
* @return Histogram.Child instance for the label combination
281
* @throws IllegalArgumentException if wrong number of labels
282
*/
283
public Histogram.Child labels(String... labelValues);
284
285
/**
286
* Remove histogram child for specific label values
287
* @param labelValues Values identifying the child to remove
288
*/
289
public void remove(String... labelValues);
290
291
/**
292
* Remove all histogram children
293
*/
294
public void clear();
295
```
296
297
### Histogram Child Operations
298
299
Histogram.Child provides the same observation and timing operations for labeled instances.
300
301
```java { .api }
302
public static class Child {
303
/** Record observation in child histogram */
304
public void observe(double amt);
305
306
/** Record observation with exemplar */
307
public void observeWithExemplar(double amt, String... exemplarLabels);
308
public void observeWithExemplar(double amt, Map<String, String> exemplarLabels);
309
310
/** Start timer for child histogram */
311
public Timer startTimer();
312
313
/** Time operations for child histogram */
314
public double time(Runnable timeable);
315
public <E> E time(Callable<E> timeable);
316
public double timeWithExemplar(Runnable timeable, String... exemplarLabels);
317
public <E> E timeWithExemplar(Callable<E> timeable, String... exemplarLabels);
318
319
/** Get histogram data snapshot */
320
public Value get();
321
}
322
```
323
324
### Histogram Value Data
325
326
Access histogram bucket counts, sum, and exemplar data.
327
328
```java { .api }
329
public static class Value {
330
/** Sum of all observed values */
331
public final double sum;
332
333
/** Cumulative counts for each bucket */
334
public final double[] buckets;
335
336
/** Exemplars for each bucket (may contain nulls) */
337
public final Exemplar[] exemplars;
338
339
/** Creation timestamp in milliseconds */
340
public final long created;
341
}
342
```
343
344
**Usage Example:**
345
346
```java
347
// HTTP request monitoring
348
Histogram httpDuration = Histogram.build()
349
.name("http_request_duration_seconds")
350
.help("HTTP request duration")
351
.labelNames("method", "status")
352
.buckets(0.001, 0.01, 0.1, 1.0, 10.0)
353
.register();
354
355
// Track requests by method and status
356
Histogram.Child getSuccess = httpDuration.labels("GET", "200");
357
Histogram.Child postError = httpDuration.labels("POST", "500");
358
359
// Time requests
360
getSuccess.time(() -> handleGetRequest());
361
postError.observe(2.5); // 2.5 second failed request
362
363
// Access histogram data
364
Histogram.Child.Value data = getSuccess.get();
365
System.out.println("Total requests: " + data.buckets[data.buckets.length - 1]);
366
System.out.println("Total duration: " + data.sum + " seconds");
367
```
368
369
## Important Notes
370
371
### Default Buckets
372
373
Histogram uses default buckets optimized for web/RPC latencies:
374
```
375
.005, .01, .025, .05, .075, .1, .25, .5, .75, 1, 2.5, 5, 7.5, 10 (seconds)
376
```
377
378
### Bucket Requirements
379
380
- Buckets must be in strictly increasing order
381
- Infinity bucket (+Inf) is automatically added
382
- At least one bucket is required
383
- Cannot use "le" as a label name (reserved for bucket labels)
384
385
### Performance Considerations
386
387
- Each bucket creates a separate time series
388
- High cardinality (many labels × many buckets) can impact performance
389
- Choose bucket boundaries based on your specific use case
390
- Consider Summary for high-cardinality scenarios
391
392
### Common Use Cases
393
394
```java
395
// API latency monitoring
396
Histogram apiLatency = Histogram.build()
397
.name("api_request_duration_seconds")
398
.help("API request latency")
399
.labelNames("endpoint", "method")
400
.buckets(0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0)
401
.register();
402
403
// File size distribution
404
Histogram fileSize = Histogram.build()
405
.name("file_size_bytes")
406
.help("File size distribution")
407
.exponentialBuckets(1024, 2, 10) // 1KB to 512KB
408
.register();
409
410
// Queue processing time
411
Histogram queueProcessing = Histogram.build()
412
.name("queue_processing_seconds")
413
.help("Queue item processing time")
414
.linearBuckets(0.1, 0.1, 10) // 0.1s to 1.0s
415
.register();
416
```