0
# Metrics Integration
1
2
Pluggable metrics system supporting popular metrics frameworks including Dropwizard Metrics and Prometheus for comprehensive pool monitoring.
3
4
## Capabilities
5
6
### Base Metrics Framework
7
8
Core metrics tracking infrastructure that provides the foundation for all metrics integrations.
9
10
```java { .api }
11
/**
12
* Base class for metrics tracking implementations. This class only supports realtime, not historical metrics.
13
*/
14
public abstract class MetricsTracker implements AutoCloseable {
15
/**
16
* Default constructor
17
*/
18
public MetricsTracker();
19
20
/**
21
* Record the time it took to acquire a connection from the pool
22
* @param elapsedAcquiredNanos time in nanoseconds to acquire the connection
23
*/
24
public void recordConnectionAcquiredNanos(long elapsedAcquiredNanos);
25
26
/**
27
* Record the time that a connection was used (from checkout to checkin)
28
* @param elapsedBorrowedMillis time in milliseconds the connection was borrowed
29
*/
30
public void recordConnectionUsageMillis(long elapsedBorrowedMillis);
31
32
/**
33
* Record a connection timeout event
34
*/
35
public void recordConnectionTimeout();
36
37
/**
38
* Close and cleanup the metrics tracker
39
*/
40
@Override
41
public void close();
42
}
43
44
/**
45
* Factory interface for creating MetricsTracker instances
46
*/
47
public interface MetricsTrackerFactory {
48
/**
49
* Create an instance of a MetricsTracker
50
* @param poolName the name of the pool
51
* @param poolStats a PoolStats instance to use
52
* @return a MetricsTracker implementation instance
53
*/
54
MetricsTracker create(String poolName, PoolStats poolStats);
55
}
56
```
57
58
**Usage Examples:**
59
60
```java
61
// Custom metrics tracker implementation
62
public class CustomMetricsTracker extends MetricsTracker {
63
private final String poolName;
64
private final AtomicLong connectionAcquisitions = new AtomicLong();
65
private final AtomicLong connectionTimeouts = new AtomicLong();
66
67
public CustomMetricsTracker(String poolName) {
68
this.poolName = poolName;
69
}
70
71
@Override
72
public void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {
73
connectionAcquisitions.incrementAndGet();
74
// Convert to milliseconds and record
75
long millis = elapsedAcquiredNanos / 1_000_000;
76
MyMetricsSystem.recordTimer("hikari.connection.acquire", millis, poolName);
77
}
78
79
@Override
80
public void recordConnectionUsageMillis(long elapsedBorrowedMillis) {
81
MyMetricsSystem.recordTimer("hikari.connection.usage", elapsedBorrowedMillis, poolName);
82
}
83
84
@Override
85
public void recordConnectionTimeout() {
86
connectionTimeouts.incrementAndGet();
87
MyMetricsSystem.incrementCounter("hikari.connection.timeout", poolName);
88
}
89
}
90
91
// Custom factory
92
public class CustomMetricsTrackerFactory implements MetricsTrackerFactory {
93
@Override
94
public MetricsTracker create(String poolName, PoolStats poolStats) {
95
return new CustomMetricsTracker(poolName);
96
}
97
}
98
```
99
100
### Pool Statistics
101
102
Abstract base class providing pool statistics for metrics systems.
103
104
```java { .api }
105
/**
106
* Abstract base class providing pool statistics with caching support
107
*/
108
public abstract class PoolStats {
109
/**
110
* Constructor with timeout for statistics caching
111
* @param timeoutMs timeout in milliseconds for statistics refresh
112
*/
113
protected PoolStats(long timeoutMs);
114
115
/**
116
* Get the total number of connections in the pool
117
* @return total connections
118
*/
119
public int getTotalConnections();
120
121
/**
122
* Get the number of idle connections in the pool
123
* @return idle connections
124
*/
125
public int getIdleConnections();
126
127
/**
128
* Get the number of active connections in the pool
129
* @return active connections
130
*/
131
public int getActiveConnections();
132
133
/**
134
* Get the number of threads waiting for connections
135
* @return pending threads
136
*/
137
public int getPendingThreads();
138
139
/**
140
* Update the statistics - implemented by subclasses
141
*/
142
protected abstract void update();
143
}
144
```
145
146
### Metrics Configuration
147
148
Configure metrics tracking through HikariConfig.
149
150
```java { .api }
151
// In HikariConfig class
152
/**
153
* Set a MetricsTrackerFactory to be used for tracking pool metrics
154
* @param metricsTrackerFactory the MetricsTrackerFactory implementation
155
*/
156
public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory);
157
public MetricsTrackerFactory getMetricsTrackerFactory();
158
159
/**
160
* Set a Codahale MetricRegistry to use for HikariCP
161
* @param metricRegistry the Codahale MetricRegistry to set
162
*/
163
public void setMetricRegistry(Object metricRegistry);
164
public Object getMetricRegistry();
165
166
/**
167
* Set a Codahale HealthCheckRegistry to use for HikariCP
168
* @param healthCheckRegistry the Codahale HealthCheckRegistry to set
169
*/
170
public void setHealthCheckRegistry(Object healthCheckRegistry);
171
public Object getHealthCheckRegistry();
172
```
173
174
**Usage Examples:**
175
176
```java
177
// Configure custom metrics factory
178
HikariConfig config = new HikariConfig();
179
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
180
config.setMetricsTrackerFactory(new CustomMetricsTrackerFactory());
181
182
// Configure Codahale Metrics (alternative approach)
183
MetricRegistry metricRegistry = new MetricRegistry();
184
config.setMetricRegistry(metricRegistry);
185
186
HikariDataSource dataSource = new HikariDataSource(config);
187
```
188
189
## Dropwizard Metrics Integration
190
191
### Dropwizard Metrics Tracker
192
193
Pre-built integration with Dropwizard (Codahale) Metrics library.
194
195
```java { .api }
196
/**
197
* Dropwizard Metrics implementation of MetricsTracker
198
*/
199
public final class CodaHaleMetricsTracker extends MetricsTracker {
200
/**
201
* Constructor with Dropwizard MetricRegistry
202
* @param poolName the name of the pool
203
* @param poolStats pool statistics instance
204
* @param registry the Dropwizard MetricRegistry
205
*/
206
public CodaHaleMetricsTracker(String poolName, PoolStats poolStats, MetricRegistry registry);
207
208
/**
209
* Get the Timer used for connection acquisition metrics
210
* @return Timer for connection acquisition
211
*/
212
public Timer getConnectionAcquisitionTimer();
213
214
/**
215
* Get the Histogram used for connection duration metrics
216
* @return Histogram for connection duration
217
*/
218
public Histogram getConnectionDurationHistogram();
219
}
220
221
/**
222
* Factory for creating Dropwizard metrics trackers
223
*/
224
public final class CodahaleMetricsTrackerFactory implements MetricsTrackerFactory {
225
/**
226
* Constructor with MetricRegistry
227
* @param registry the Dropwizard MetricRegistry
228
*/
229
public CodahaleMetricsTrackerFactory(MetricRegistry registry);
230
231
/**
232
* Get the MetricRegistry used by this factory
233
* @return the MetricRegistry
234
*/
235
public MetricRegistry getRegistry();
236
237
@Override
238
public MetricsTracker create(String poolName, PoolStats poolStats);
239
}
240
```
241
242
**Usage Examples:**
243
244
```java
245
import com.codahale.metrics.MetricRegistry;
246
import com.codahale.metrics.ConsoleReporter;
247
import com.zaxxer.hikari.metrics.dropwizard.CodahaleMetricsTrackerFactory;
248
249
// Setup Dropwizard Metrics
250
MetricRegistry metricRegistry = new MetricRegistry();
251
252
// Optional: Setup console reporter
253
ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry)
254
.convertRatesTo(TimeUnit.SECONDS)
255
.convertDurationsTo(TimeUnit.MILLISECONDS)
256
.build();
257
reporter.start(1, TimeUnit.MINUTES);
258
259
// Configure HikariCP with Dropwizard Metrics
260
HikariConfig config = new HikariConfig();
261
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
262
config.setMetricsTrackerFactory(new CodahaleMetricsTrackerFactory(metricRegistry));
263
264
HikariDataSource dataSource = new HikariDataSource(config);
265
266
// Access specific metrics
267
CodaHaleMetricsTracker tracker = (CodaHaleMetricsTracker)
268
dataSource.getMetricsTrackerFactory().create("test", null);
269
Timer acquisitionTimer = tracker.getConnectionAcquisitionTimer();
270
Histogram usageHistogram = tracker.getConnectionDurationHistogram();
271
```
272
273
### Dropwizard Health Checks
274
275
Health check integration for monitoring pool health.
276
277
```java { .api }
278
/**
279
* Dropwizard HealthCheck implementation for HikariCP
280
*/
281
public final class CodahaleHealthChecker extends HealthCheck {
282
// Implementation details are internal to the health check framework
283
}
284
```
285
286
**Usage Examples:**
287
288
```java
289
import com.codahale.metrics.health.HealthCheckRegistry;
290
import com.zaxxer.hikari.metrics.dropwizard.CodahaleHealthChecker;
291
292
// Setup health check registry
293
HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
294
295
// Configure HikariCP with health checks
296
HikariConfig config = new HikariConfig();
297
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
298
config.setHealthCheckRegistry(healthCheckRegistry);
299
300
// Add health check properties
301
config.addHealthCheckProperty("connectivityCheckTimeoutMs", "5000");
302
config.addHealthCheckProperty("expected99thPercentileMs", "100");
303
304
HikariDataSource dataSource = new HikariDataSource(config);
305
306
// Run health checks
307
Map<String, HealthCheck.Result> results = healthCheckRegistry.runHealthChecks();
308
for (Map.Entry<String, HealthCheck.Result> entry : results.entrySet()) {
309
System.out.println(entry.getKey() + ": " +
310
(entry.getValue().isHealthy() ? "HEALTHY" : "UNHEALTHY"));
311
}
312
```
313
314
## Prometheus Metrics Integration
315
316
### Prometheus Metrics Tracker
317
318
Pre-built integration with Prometheus metrics collection.
319
320
```java { .api }
321
/**
322
* Factory for creating Prometheus metrics trackers
323
*/
324
public class PrometheusMetricsTrackerFactory implements MetricsTrackerFactory {
325
/**
326
* Create a Prometheus metrics tracker and register collectors
327
* @param poolName the name of the pool
328
* @param poolStats pool statistics instance
329
* @return PrometheusMetricsTracker instance
330
*/
331
@Override
332
public MetricsTracker create(String poolName, PoolStats poolStats);
333
}
334
```
335
336
**Usage Examples:**
337
338
```java
339
import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory;
340
import io.prometheus.client.CollectorRegistry;
341
import io.prometheus.client.exporter.HTTPServer;
342
343
// Configure HikariCP with Prometheus
344
HikariConfig config = new HikariConfig();
345
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
346
config.setMetricsTrackerFactory(new PrometheusMetricsTrackerFactory());
347
348
HikariDataSource dataSource = new HikariDataSource(config);
349
350
// Start Prometheus HTTP server for metrics scraping
351
HTTPServer server = new HTTPServer(8080);
352
353
// Metrics will be available at http://localhost:8080/metrics
354
// Example metrics exposed:
355
// - hikaricp_connection_timeout_count{pool="mypool"}
356
// - hikaricp_connection_acquired_nanos{pool="mypool",quantile="0.5"}
357
// - hikaricp_connection_usage_millis{pool="mypool",quantile="0.95"}
358
```
359
360
### Prometheus Collector
361
362
HikariCP-specific Prometheus collector for pool statistics.
363
364
```java { .api }
365
/**
366
* Prometheus collector for HikariCP pool statistics
367
*/
368
public class HikariCPCollector extends Collector {
369
// Collector implementation registers automatically when MetricsTrackerFactory is used
370
}
371
```
372
373
**Usage Examples:**
374
375
```java
376
// The HikariCPCollector is automatically registered when using PrometheusMetricsTrackerFactory
377
// It exposes the following metrics:
378
379
// Pool connection statistics
380
// - hikaricp_active_connections{pool="poolName"} - Active connections
381
// - hikaricp_idle_connections{pool="poolName"} - Idle connections
382
// - hikaricp_pending_threads{pool="poolName"} - Threads waiting for connections
383
// - hikaricp_connections{pool="poolName"} - Total connections
384
385
// Connection timing metrics (from PrometheusMetricsTracker)
386
// - hikaricp_connection_acquired_nanos{pool="poolName"} - Connection acquisition time
387
// - hikaricp_connection_usage_millis{pool="poolName"} - Connection usage time
388
// - hikaricp_connection_timeout_count{pool="poolName"} - Connection timeout count
389
390
// Example Prometheus query for monitoring
391
// Rate of connection acquisitions:
392
// rate(hikaricp_connection_acquired_nanos_count[5m])
393
394
// 95th percentile connection acquisition time:
395
// hikaricp_connection_acquired_nanos{quantile="0.95"}
396
397
// Pool utilization percentage:
398
// (hikaricp_active_connections / hikaricp_connections) * 100
399
```
400
401
## Custom Metrics Integration
402
403
### Building Custom Metrics Integrations
404
405
Create custom integrations for other metrics systems.
406
407
**Usage Examples:**
408
409
```java
410
// Example: Micrometer integration
411
public class MicrometerMetricsTracker extends MetricsTracker {
412
private final MeterRegistry meterRegistry;
413
private final Timer acquisitionTimer;
414
private final Timer usageTimer;
415
private final Counter timeoutCounter;
416
private final String poolName;
417
418
public MicrometerMetricsTracker(String poolName, MeterRegistry meterRegistry) {
419
this.poolName = poolName;
420
this.meterRegistry = meterRegistry;
421
422
this.acquisitionTimer = Timer.builder("hikari.connection.acquire")
423
.tag("pool", poolName)
424
.description("Connection acquisition time")
425
.register(meterRegistry);
426
427
this.usageTimer = Timer.builder("hikari.connection.usage")
428
.tag("pool", poolName)
429
.description("Connection usage time")
430
.register(meterRegistry);
431
432
this.timeoutCounter = Counter.builder("hikari.connection.timeout")
433
.tag("pool", poolName)
434
.description("Connection timeout count")
435
.register(meterRegistry);
436
}
437
438
@Override
439
public void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {
440
acquisitionTimer.record(elapsedAcquiredNanos, TimeUnit.NANOSECONDS);
441
}
442
443
@Override
444
public void recordConnectionUsageMillis(long elapsedBorrowedMillis) {
445
usageTimer.record(elapsedBorrowedMillis, TimeUnit.MILLISECONDS);
446
}
447
448
@Override
449
public void recordConnectionTimeout() {
450
timeoutCounter.increment();
451
}
452
453
@Override
454
public void close() {
455
// Cleanup if needed
456
meterRegistry.remove(acquisitionTimer);
457
meterRegistry.remove(usageTimer);
458
meterRegistry.remove(timeoutCounter);
459
}
460
}
461
462
public class MicrometerMetricsTrackerFactory implements MetricsTrackerFactory {
463
private final MeterRegistry meterRegistry;
464
465
public MicrometerMetricsTrackerFactory(MeterRegistry meterRegistry) {
466
this.meterRegistry = meterRegistry;
467
}
468
469
@Override
470
public MetricsTracker create(String poolName, PoolStats poolStats) {
471
// Register pool statistics gauges
472
Gauge.builder("hikari.connections.active")
473
.tag("pool", poolName)
474
.register(meterRegistry, poolStats, PoolStats::getActiveConnections);
475
476
Gauge.builder("hikari.connections.idle")
477
.tag("pool", poolName)
478
.register(meterRegistry, poolStats, PoolStats::getIdleConnections);
479
480
Gauge.builder("hikari.connections.total")
481
.tag("pool", poolName)
482
.register(meterRegistry, poolStats, PoolStats::getTotalConnections);
483
484
Gauge.builder("hikari.connections.pending")
485
.tag("pool", poolName)
486
.register(meterRegistry, poolStats, PoolStats::getPendingThreads);
487
488
return new MicrometerMetricsTracker(poolName, meterRegistry);
489
}
490
}
491
492
// Usage
493
MeterRegistry meterRegistry = new SimpleMeterRegistry();
494
HikariConfig config = new HikariConfig();
495
config.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(meterRegistry));
496
```