0
# Metrics Integration
1
2
Pluggable metrics system supporting Micrometer, Dropwizard/Codahale, and Prometheus monitoring frameworks.
3
4
## Capabilities
5
6
### Core Metrics Interfaces
7
8
Base interfaces for implementing custom metrics tracking.
9
10
```java { .api }
11
/**
12
* Factory interface for creating metrics trackers
13
*/
14
public interface MetricsTrackerFactory {
15
/**
16
* Create a metrics tracker instance for a specific pool
17
* @param poolName Name of the connection pool
18
* @param poolStats PoolStats instance for accessing pool metrics
19
* @return IMetricsTracker implementation
20
*/
21
IMetricsTracker create(String poolName, PoolStats poolStats);
22
}
23
24
/**
25
* Interface for tracking pool metrics
26
* All methods have default empty implementations for optional tracking
27
*/
28
public interface IMetricsTracker extends AutoCloseable {
29
30
/**
31
* Record time taken to create a new connection
32
* @param connectionCreatedMillis Time in milliseconds
33
*/
34
default void recordConnectionCreatedMillis(long connectionCreatedMillis) {}
35
36
/**
37
* Record time taken to acquire connection from pool
38
* @param elapsedAcquiredNanos Time in nanoseconds
39
*/
40
default void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {}
41
42
/**
43
* Record time connection was borrowed from pool
44
* @param elapsedBorrowedMillis Time in milliseconds
45
*/
46
default void recordConnectionUsageMillis(long elapsedBorrowedMillis) {}
47
48
/**
49
* Record connection timeout event
50
*/
51
default void recordConnectionTimeout() {}
52
53
/**
54
* Close and cleanup metrics resources
55
*/
56
@Override
57
default void close() {}
58
}
59
60
/**
61
* Abstract base class providing pool statistics
62
*/
63
public abstract class PoolStats {
64
/**
65
* Constructor with cache timeout
66
* @param timeoutMs Cache timeout in milliseconds
67
*/
68
public PoolStats(long timeoutMs);
69
70
// Pool statistics (cached for performance)
71
public int getTotalConnections();
72
public int getIdleConnections();
73
public int getActiveConnections();
74
public int getPendingThreads();
75
public int getMaxConnections();
76
public int getMinConnections();
77
78
/**
79
* Update statistics - implemented by concrete classes
80
*/
81
protected abstract void update();
82
}
83
```
84
85
### Micrometer Integration
86
87
Integration with Micrometer metrics framework for Spring Boot and cloud-native applications.
88
89
```java { .api }
90
/**
91
* Micrometer metrics tracker factory
92
*/
93
public class MicrometerMetricsTrackerFactory implements MetricsTrackerFactory {
94
95
/**
96
* Create factory with MeterRegistry
97
* @param meterRegistry Micrometer MeterRegistry instance
98
*/
99
public MicrometerMetricsTrackerFactory(MeterRegistry meterRegistry);
100
101
/**
102
* Create tracker for specific pool
103
*/
104
@Override
105
public IMetricsTracker create(String poolName, PoolStats poolStats);
106
}
107
108
/**
109
* Micrometer metrics tracker implementation
110
*/
111
public class MicrometerMetricsTracker implements IMetricsTracker {
112
// Tracks metrics using Micrometer Timer and Counter
113
}
114
```
115
116
**Micrometer Usage Examples:**
117
118
```java
119
import io.micrometer.core.instrument.MeterRegistry;
120
import io.micrometer.prometheus.PrometheusConfig;
121
import io.micrometer.prometheus.PrometheusMeterRegistry;
122
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
123
124
// Setup Micrometer with Prometheus
125
MeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
126
127
// Configure HikariCP with Micrometer
128
HikariConfig config = new HikariConfig();
129
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
130
config.setUsername("user");
131
config.setPassword("pass");
132
config.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(registry));
133
config.setPoolName("MyApp-DB"); // Required for metrics labeling
134
135
HikariDataSource dataSource = new HikariDataSource(config);
136
137
// Metrics are automatically tracked and available in registry
138
```
139
140
**Micrometer Metrics Exported:**
141
142
- `hikaricp.connections.active` - Active connections gauge
143
- `hikaricp.connections.idle` - Idle connections gauge
144
- `hikaricp.connections.pending` - Pending threads gauge
145
- `hikaricp.connections.total` - Total connections gauge
146
- `hikaricp.connections.min` - Minimum connections gauge
147
- `hikaricp.connections.max` - Maximum connections gauge
148
- `hikaricp.connections.creation` - Connection creation timer
149
- `hikaricp.connections.acquire` - Connection acquisition timer
150
- `hikaricp.connections.usage` - Connection usage timer
151
- `hikaricp.connections.timeout` - Connection timeout counter
152
153
### Dropwizard/Codahale Metrics Integration
154
155
Integration with Dropwizard Metrics (formerly Codahale Metrics) framework.
156
157
```java { .api }
158
/**
159
* Codahale/Dropwizard 4.x metrics factory
160
*/
161
public class CodahaleMetricsTrackerFactory implements MetricsTrackerFactory {
162
163
/**
164
* Create factory with MetricRegistry
165
* @param registry Dropwizard MetricRegistry
166
*/
167
public CodahaleMetricsTrackerFactory(MetricRegistry registry);
168
169
/**
170
* Create factory with MetricRegistry and HealthCheckRegistry
171
* @param registry Dropwizard MetricRegistry
172
* @param healthCheckRegistry HealthCheckRegistry for connection health checks
173
*/
174
public CodahaleMetricsTrackerFactory(MetricRegistry registry,
175
HealthCheckRegistry healthCheckRegistry);
176
}
177
178
/**
179
* Dropwizard 5.x metrics factory
180
*/
181
public class Dropwizard5MetricsTrackerFactory implements MetricsTrackerFactory {
182
/**
183
* Create factory for Dropwizard 5.x
184
*/
185
public Dropwizard5MetricsTrackerFactory(io.dropwizard.metrics5.MetricRegistry registry);
186
}
187
188
/**
189
* Health check implementation for Codahale metrics
190
*/
191
public class CodahaleHealthChecker extends HealthCheck {
192
/**
193
* Create health checker for pool
194
* @param dataSource HikariDataSource to monitor
195
* @param timeout Health check timeout
196
*/
197
public CodahaleHealthChecker(HikariDataSource dataSource, long timeout);
198
}
199
```
200
201
**Dropwizard Usage Examples:**
202
203
```java
204
import com.codahale.metrics.MetricRegistry;
205
import com.codahale.metrics.health.HealthCheckRegistry;
206
import com.zaxxer.hikari.metrics.dropwizard.CodahaleMetricsTrackerFactory;
207
import com.zaxxer.hikari.metrics.dropwizard.CodahaleHealthChecker;
208
209
// Setup Dropwizard metrics
210
MetricRegistry metricRegistry = new MetricRegistry();
211
HealthCheckRegistry healthRegistry = new HealthCheckRegistry();
212
213
// Configure HikariCP with Dropwizard
214
HikariConfig config = new HikariConfig();
215
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
216
config.setUsername("user");
217
config.setPassword("pass");
218
config.setMetricsTrackerFactory(
219
new CodahaleMetricsTrackerFactory(metricRegistry, healthRegistry));
220
config.setPoolName("MyApp-DB");
221
222
HikariDataSource dataSource = new HikariDataSource(config);
223
224
// Register health check
225
healthRegistry.register("hikari-pool",
226
new CodahaleHealthChecker(dataSource, 3000));
227
228
// Metrics available in MetricRegistry:
229
// - pool.Wait (timer) - time to acquire connection
230
// - pool.Usage (timer) - time connection is borrowed
231
// - pool.ConnectionCreation (timer) - time to create connection
232
// - pool.TotalConnections (gauge) - total connections
233
// - pool.IdleConnections (gauge) - idle connections
234
// - pool.ActiveConnections (gauge) - active connections
235
// - pool.PendingConnections (gauge) - pending threads
236
```
237
238
### Prometheus Integration
239
240
Direct integration with Prometheus metrics collection.
241
242
```java { .api }
243
/**
244
* Prometheus metrics tracker factory (summary-based)
245
*/
246
public class PrometheusMetricsTrackerFactory implements MetricsTrackerFactory {
247
248
/**
249
* Create factory with CollectorRegistry
250
* @param collectorRegistry Prometheus CollectorRegistry
251
*/
252
public PrometheusMetricsTrackerFactory(CollectorRegistry collectorRegistry);
253
254
/**
255
* Create factory with default registry
256
*/
257
public PrometheusMetricsTrackerFactory();
258
}
259
260
/**
261
* Prometheus histogram-based metrics factory
262
*/
263
public class PrometheusHistogramMetricsTrackerFactory implements MetricsTrackerFactory {
264
265
/**
266
* Create histogram factory with custom buckets
267
* @param collectorRegistry Prometheus CollectorRegistry
268
*/
269
public PrometheusHistogramMetricsTrackerFactory(CollectorRegistry collectorRegistry);
270
271
/**
272
* Create histogram factory with default registry and buckets
273
*/
274
public PrometheusHistogramMetricsTrackerFactory();
275
}
276
277
/**
278
* Prometheus collector for HikariCP metrics
279
*/
280
public class HikariCPCollector extends Collector {
281
282
/**
283
* Create collector for multiple HikariCP pools
284
*/
285
public HikariCPCollector();
286
287
/**
288
* Add HikariDataSource to collector
289
* @param dataSource HikariDataSource to monitor
290
* @return this collector for chaining
291
*/
292
public HikariCPCollector add(String name, HikariDataSource dataSource);
293
}
294
```
295
296
**Prometheus Usage Examples:**
297
298
```java
299
import io.prometheus.client.CollectorRegistry;
300
import io.prometheus.client.exporter.HTTPServer;
301
import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory;
302
import com.zaxxer.hikari.metrics.prometheus.HikariCPCollector;
303
304
// Method 1: Using PrometheusMetricsTrackerFactory
305
CollectorRegistry registry = CollectorRegistry.defaultRegistry;
306
307
HikariConfig config = new HikariConfig();
308
config.setJdbcUrl("jdbc:h2:mem:test");
309
config.setMetricsTrackerFactory(new PrometheusMetricsTrackerFactory(registry));
310
config.setPoolName("test-pool");
311
312
HikariDataSource dataSource = new HikariDataSource(config);
313
314
// Method 2: Using HikariCPCollector (multiple pools)
315
HikariCPCollector collector = new HikariCPCollector()
316
.add("primary-db", primaryDataSource)
317
.add("cache-db", cacheDataSource)
318
.add("analytics-db", analyticsDataSource);
319
320
CollectorRegistry.defaultRegistry.register(collector);
321
322
// Start HTTP server for Prometheus scraping
323
HTTPServer server = new HTTPServer(8080);
324
325
// Method 3: Histogram-based metrics (better for percentiles)
326
config.setMetricsTrackerFactory(
327
new PrometheusHistogramMetricsTrackerFactory(registry));
328
```
329
330
**Prometheus Metrics Exported:**
331
332
```
333
# Connection pool size metrics
334
hikaricp_active_connections{pool="test-pool"} 5
335
hikaricp_idle_connections{pool="test-pool"} 3
336
hikaricp_pending_threads{pool="test-pool"} 0
337
hikaricp_total_connections{pool="test-pool"} 8
338
339
# Timing metrics (summary)
340
hikaricp_connection_acquire_nanos{pool="test-pool",quantile="0.5"} 1200000
341
hikaricp_connection_acquire_nanos{pool="test-pool",quantile="0.95"} 5000000
342
hikaricp_connection_acquire_nanos_count{pool="test-pool"} 1000
343
hikaricp_connection_acquire_nanos_sum{pool="test-pool"} 1500000000
344
345
# Connection usage timing
346
hikaricp_connection_usage_millis{pool="test-pool",quantile="0.99"} 150
347
hikaricp_connection_usage_millis_count{pool="test-pool"} 950
348
349
# Connection creation timing
350
hikaricp_connection_creation_millis{pool="test-pool",quantile="0.95"} 50
351
352
# Timeout events
353
hikaricp_connection_timeout_total{pool="test-pool"} 2
354
```
355
356
### Custom Metrics Implementation
357
358
Create custom metrics integration for other monitoring systems.
359
360
```java
361
import com.zaxxer.hikari.metrics.IMetricsTracker;
362
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
363
import com.zaxxer.hikari.metrics.PoolStats;
364
365
/**
366
* Custom metrics tracker factory
367
*/
368
public class CustomMetricsTrackerFactory implements MetricsTrackerFactory {
369
370
private final MyMonitoringSystem monitoringSystem;
371
372
public CustomMetricsTrackerFactory(MyMonitoringSystem system) {
373
this.monitoringSystem = system;
374
}
375
376
@Override
377
public IMetricsTracker create(String poolName, PoolStats poolStats) {
378
return new CustomMetricsTracker(poolName, poolStats, monitoringSystem);
379
}
380
}
381
382
/**
383
* Custom metrics tracker implementation
384
*/
385
public class CustomMetricsTracker implements IMetricsTracker {
386
387
private final String poolName;
388
private final PoolStats poolStats;
389
private final MyMonitoringSystem monitoring;
390
391
public CustomMetricsTracker(String poolName, PoolStats poolStats,
392
MyMonitoringSystem monitoring) {
393
this.poolName = poolName;
394
this.poolStats = poolStats;
395
this.monitoring = monitoring;
396
397
// Start background thread to report pool stats
398
startStatsReporting();
399
}
400
401
@Override
402
public void recordConnectionCreatedMillis(long connectionCreatedMillis) {
403
monitoring.recordTimer("hikari.connection.creation",
404
connectionCreatedMillis, "pool", poolName);
405
}
406
407
@Override
408
public void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {
409
monitoring.recordTimer("hikari.connection.acquire",
410
elapsedAcquiredNanos / 1_000_000, "pool", poolName);
411
}
412
413
@Override
414
public void recordConnectionUsageMillis(long elapsedBorrowedMillis) {
415
monitoring.recordTimer("hikari.connection.usage",
416
elapsedBorrowedMillis, "pool", poolName);
417
}
418
419
@Override
420
public void recordConnectionTimeout() {
421
monitoring.incrementCounter("hikari.connection.timeout", "pool", poolName);
422
}
423
424
private void startStatsReporting() {
425
// Report pool statistics periodically
426
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
427
executor.scheduleAtFixedRate(() -> {
428
monitoring.recordGauge("hikari.connections.active",
429
poolStats.getActiveConnections(), "pool", poolName);
430
monitoring.recordGauge("hikari.connections.idle",
431
poolStats.getIdleConnections(), "pool", poolName);
432
monitoring.recordGauge("hikari.connections.total",
433
poolStats.getTotalConnections(), "pool", poolName);
434
}, 0, 30, TimeUnit.SECONDS);
435
}
436
437
@Override
438
public void close() {
439
// Cleanup resources
440
}
441
}
442
443
// Usage
444
HikariConfig config = new HikariConfig();
445
config.setMetricsTrackerFactory(new CustomMetricsTrackerFactory(myMonitoringSystem));
446
```
447
448
### Metrics Configuration
449
450
Configure metrics collection and reporting behavior.
451
452
```java
453
// Enable metrics collection
454
HikariConfig config = new HikariConfig();
455
config.setPoolName("MyPool"); // Required for metrics labeling
456
457
// Choose metrics implementation
458
config.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(meterRegistry));
459
460
// Alternative: Use metric registry directly (Dropwizard/Codahale)
461
config.setMetricRegistry(metricRegistry);
462
463
// Health check integration (Dropwizard)
464
config.setHealthCheckRegistry(healthCheckRegistry);
465
config.addHealthCheckProperty("connectivityCheck", "true");
466
config.addHealthCheckProperty("expected99thPercentileMs", "100");
467
468
HikariDataSource dataSource = new HikariDataSource(config);
469
```
470
471
**Metrics Best Practices:**
472
473
1. **Always set pool name** - Required for proper metric labeling
474
2. **Use appropriate factory** - Choose based on your monitoring stack
475
3. **Monitor key metrics** - Focus on acquisition time, active connections, timeouts
476
4. **Set up alerting** - Alert on high acquisition times and timeouts
477
5. **Regular cleanup** - Ensure metrics resources are properly closed