CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-zaxxer--hikari-cp-java6

Ultimate JDBC Connection Pool - Java 6 compatible version providing high-performance database connection pooling

Pending
Overview
Eval results
Files

metrics-monitoring.mddocs/

Metrics and Monitoring

Comprehensive metrics collection and health monitoring through integration with popular metrics libraries like Codahale Metrics (Dropwizard Metrics), providing detailed insights into connection pool performance, usage patterns, and health status.

Capabilities

MetricsTracker

Base class for metrics tracking functionality, providing a framework for collecting and reporting connection pool metrics.

public class MetricsTracker {
    /**
     * No-operation metrics context for disabled metrics.
     */
    public static final MetricsContext NO_CONTEXT;
    
    /**
     * Create metrics tracker with pool reference.
     * 
     * @param pool the BaseHikariPool to track
     */
    public MetricsTracker(BaseHikariPool pool);
    
    /**
     * Record a connection request and return timing context.
     * 
     * @param requestTime timestamp when request was made
     * @return MetricsContext for timing the request
     */
    public MetricsContext recordConnectionRequest(long requestTime);
    
    /**
     * Record connection usage statistics.
     * 
     * @param bagEntry the PoolBagEntry representing the connection
     */
    public void recordConnectionUsage(PoolBagEntry bagEntry);
    
    /**
     * Close the metrics tracker and release resources.
     */
    public void close();
}

MetricsContext

Inner class providing context for timing operations and tracking connection lifecycle events.

public static class MetricsContext {
    /**
     * Stop timing the current operation.
     */
    public void stop();
    
    /**
     * Set the last open time for a connection.
     * 
     * @param bagEntry the PoolBagEntry representing the connection
     * @param now current timestamp
     */
    public void setConnectionLastOpen(PoolBagEntry bagEntry, long now);
}

CodaHaleMetricsTracker

Integration with Codahale Metrics (Dropwizard Metrics) library, providing detailed timing and histogram metrics for connection pool operations.

public class CodaHaleMetricsTracker extends MetricsTracker {
    /**
     * Create Codahale metrics tracker with registry.
     * Automatically registers the following metrics:
     * - Timer: {poolName}.pool.Wait (connection acquisition time)
     * - Histogram: {poolName}.pool.Usage (connection usage duration)
     * - Gauge: {poolName}.pool.TotalConnections (total connections in pool)
     * - Gauge: {poolName}.pool.IdleConnections (idle connections available)
     * - Gauge: {poolName}.pool.ActiveConnections (active connections in use)
     * - Gauge: {poolName}.pool.PendingConnections (threads waiting for connections)
     * 
     * @param pool the BaseHikariPool to track
     * @param registry the MetricRegistry to register metrics with
     */
    public CodaHaleMetricsTracker(BaseHikariPool pool, MetricRegistry registry);
    
    /**
     * Get timer for connection acquisition operations.
     * 
     * @return Timer measuring connection acquisition time
     */
    public Timer getConnectionAcquisitionTimer();
    
    /**
     * Get histogram for connection duration statistics.
     * 
     * @return Histogram measuring connection usage duration
     */
    public Histogram getConnectionDurationHistogram();
}

CodaHaleMetricsTracker.Context

Codahale-specific metrics context extending base functionality with Timer.Context integration.

public static final class Context extends MetricsContext {
    /**
     * Create context with Codahale Timer for timing operations.
     * 
     * @param timer Codahale Timer instance
     */
    Context(Timer timer);
    
    /**
     * Stop timing and record the measurement.
     * Overrides base implementation to stop underlying Timer.Context.
     */
    @Override
    public void stop();
    
    /**
     * Set connection last open time for usage tracking.
     * 
     * @param bagEntry the PoolBagEntry
     * @param now timestamp when connection was opened
     */
    @Override
    public void setConnectionLastOpen(PoolBagEntry bagEntry, long now);
}

CodahaleHealthChecker

Health check integration with Codahale HealthCheckRegistry for monitoring connection pool health.

public class CodahaleHealthChecker {
    /**
     * Register health checks for the specified pool with the health check registry.
     * 
     * @param pool the BaseHikariPool to monitor
     * @param registry the HealthCheckRegistry to register health checks with
     */
    public static void registerHealthChecks(BaseHikariPool pool, HealthCheckRegistry registry);
}

Usage Examples

Basic Metrics Configuration

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;

// Create metrics registry
MetricRegistry metricRegistry = new MetricRegistry();
HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();

// Configure HikariCP with metrics
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost/mydb");
config.setUsername("user");
config.setPassword("password");
config.setPoolName("MonitoredPool");

// Enable metrics collection
config.setMetricRegistry(metricRegistry);
config.setHealthCheckRegistry(healthCheckRegistry);

// Create DataSource with metrics enabled
HikariDataSource dataSource = new HikariDataSource(config);

Advanced Metrics Setup with Custom Properties

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import java.util.Properties;

// Create registries
MetricRegistry metricRegistry = new MetricRegistry();
HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();

// Configure connection pool
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/myapp");
config.setUsername("appuser");
config.setPassword("apppass");
config.setPoolName("MyAppPool");
config.setMaximumPoolSize(20);

// Configure metrics
config.setMetricRegistry(metricRegistry);
config.setHealthCheckRegistry(healthCheckRegistry);

// Configure health check properties
Properties healthCheckProps = new Properties();
healthCheckProps.setProperty("connectivityCheck", "true");
healthCheckProps.setProperty("connectivityCheckTimeoutMs", "1000");
healthCheckProps.setProperty("expected99thPercentileMs", "100");
config.setHealthCheckProperties(healthCheckProps);

// Alternative: Add individual health check properties
config.addHealthCheckProperty("connectivityCheck", "true");
config.addHealthCheckProperty("expected99thPercentileMs", "50");

HikariDataSource dataSource = new HikariDataSource(config);

Monitoring with Console Reporter

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.MetricRegistry;
import java.util.concurrent.TimeUnit;

// Create and configure metrics registry
MetricRegistry metricRegistry = new MetricRegistry();

// Setup HikariCP with metrics (as shown above)
HikariConfig config = new HikariConfig();
// ... basic configuration
config.setMetricRegistry(metricRegistry);
config.setPoolName("ConsoleMonitoredPool");

HikariDataSource dataSource = new HikariDataSource(config);

// Create console reporter to output metrics
ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry)
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.MILLISECONDS)
    .build();

// Start reporting every 30 seconds
reporter.start(30, TimeUnit.SECONDS);

// Use the connection pool
try (Connection conn = dataSource.getConnection()) {
    // Database operations - metrics will be collected automatically
    PreparedStatement stmt = conn.prepareStatement("SELECT COUNT(*) FROM users");
    ResultSet rs = stmt.executeQuery();
    // ...
}

// Stop reporting when shutting down
reporter.stop();
dataSource.close();

JMX Metrics Reporting

import com.codahale.metrics.JmxReporter;
import com.codahale.metrics.MetricRegistry;

// Create metrics registry
MetricRegistry metricRegistry = new MetricRegistry();

// Configure HikariCP with metrics
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:h2:mem:testdb");
config.setUsername("sa");
config.setPassword("");
config.setPoolName("JMXMonitoredPool");
config.setMetricRegistry(metricRegistry);

HikariDataSource dataSource = new HikariDataSource(config);

// Create JMX reporter
JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry)
    .inDomain("com.myapp.hikari.metrics")
    .build();

// Start JMX reporting
jmxReporter.start();

// Metrics will now be available via JMX at:
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.Wait
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.Usage
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.TotalConnections
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.IdleConnections
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.ActiveConnections
// com.myapp.hikari.metrics:name=JMXMonitoredPool.pool.PendingConnections

// Stop JMX reporting when shutting down
jmxReporter.stop();
dataSource.close();

Health Check Monitoring

import com.codahale.metrics.health.HealthCheck;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.zaxxer.hikari.metrics.CodahaleHealthChecker;

// Create health check registry
HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();

// Configure HikariCP with health checks
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost/mydb");
config.setUsername("user");
config.setPassword("password");
config.setPoolName("HealthMonitoredPool");
config.setHealthCheckRegistry(healthCheckRegistry);

// Configure health check properties
config.addHealthCheckProperty("connectivityCheck", "true");
config.addHealthCheckProperty("connectivityCheckTimeoutMs", "3000");

HikariDataSource dataSource = new HikariDataSource(config);

// Health checks are automatically registered by HikariCP
// Check health status programmatically
Map<String, HealthCheck.Result> results = healthCheckRegistry.runHealthChecks();

for (Map.Entry<String, HealthCheck.Result> entry : results.entrySet()) {
    String healthCheckName = entry.getKey();
    HealthCheck.Result result = entry.getValue();
    
    if (result.isHealthy()) {
        System.out.println(healthCheckName + ": HEALTHY");
        if (result.getMessage() != null) {
            System.out.println("  Message: " + result.getMessage());
        }
    } else {
        System.err.println(healthCheckName + ": UNHEALTHY");
        System.err.println("  Message: " + result.getMessage());
        if (result.getError() != null) {
            System.err.println("  Error: " + result.getError().getMessage());
        }
    }
}

Custom Metrics Collection

import com.codahale.metrics.*;
import com.zaxxer.hikari.metrics.CodaHaleMetricsTracker;

// Access HikariCP's Codahale metrics tracker
HikariDataSource dataSource = // ... configured with MetricRegistry

// Get metrics from the registry by pool name
MetricRegistry registry = (MetricRegistry) dataSource.getMetricRegistry();
String poolName = dataSource.getPoolName();

// Connection acquisition timing
Timer connectionAcquisitionTimer = registry.getTimer(poolName + ".pool.Wait");
System.out.println("Connection Acquisition Stats:");
System.out.println("  Count: " + connectionAcquisitionTimer.getCount());
System.out.println("  Mean: " + connectionAcquisitionTimer.getSnapshot().getMean() / 1000000 + "ms");
System.out.println("  95th percentile: " + connectionAcquisitionTimer.getSnapshot().get95thPercentile() / 1000000 + "ms");
System.out.println("  99th percentile: " + connectionAcquisitionTimer.getSnapshot().get99thPercentile() / 1000000 + "ms");

// Connection usage duration
Histogram connectionUsageHistogram = registry.getHistogram(poolName + ".pool.Usage");
System.out.println("\nConnection Usage Stats:");
System.out.println("  Count: " + connectionUsageHistogram.getCount());
System.out.println("  Mean duration: " + connectionUsageHistogram.getSnapshot().getMean() / 1000000 + "ms");
System.out.println("  Max duration: " + connectionUsageHistogram.getSnapshot().getMax() / 1000000 + "ms");

// Pool size gauges
Gauge<Integer> totalConnections = registry.getGauge(poolName + ".pool.TotalConnections");
Gauge<Integer> activeConnections = registry.getGauge(poolName + ".pool.ActiveConnections");
Gauge<Integer> idleConnections = registry.getGauge(poolName + ".pool.IdleConnections");
Gauge<Integer> pendingConnections = registry.getGauge(poolName + ".pool.PendingConnections");

System.out.println("\nPool Status:");
System.out.println("  Total: " + totalConnections.getValue());
System.out.println("  Active: " + activeConnections.getValue());
System.out.println("  Idle: " + idleConnections.getValue());
System.out.println("  Pending: " + pendingConnections.getValue());

Integration with Monitoring Systems

Prometheus Integration

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.dropwizard.DropwizardExports;
import io.prometheus.client.exporter.HTTPServer;

// Create Dropwizard MetricRegistry
MetricRegistry metricRegistry = new MetricRegistry();

// Configure HikariCP with metrics
HikariConfig config = new HikariConfig();
// ... basic configuration
config.setMetricRegistry(metricRegistry);
config.setPoolName("PrometheusPool");

HikariDataSource dataSource = new HikariDataSource(config);

// Export Dropwizard metrics to Prometheus
CollectorRegistry.defaultRegistry.register(new DropwizardExports(metricRegistry));

// Start Prometheus HTTP server (optional - for pull-based metrics)
HTTPServer server = new HTTPServer(8080);
System.out.println("Prometheus metrics available at http://localhost:8080/metrics");

// Metrics will be available with names like:
// hikaricp_PrometheusPool_pool_Wait_seconds
// hikaricp_PrometheusPool_pool_Usage_seconds
// hikaricp_PrometheusPool_pool_TotalConnections

Graphite Integration

import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

// Create metrics registry
MetricRegistry metricRegistry = new MetricRegistry();

// Configure HikariCP
HikariConfig config = new HikariConfig();
// ... configuration
config.setMetricRegistry(metricRegistry);
config.setPoolName("GraphitePool");

HikariDataSource dataSource = new HikariDataSource(config);

// Setup Graphite reporter
Graphite graphite = new Graphite(new InetSocketAddress("graphite.example.com", 2003));
GraphiteReporter reporter = GraphiteReporter.forRegistry(metricRegistry)
    .prefixedWith("myapp.database.hikaricp")
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.MILLISECONDS)
    .build(graphite);

// Start reporting every 10 seconds
reporter.start(10, TimeUnit.SECONDS);

Alerting Based on Metrics

import com.codahale.metrics.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

// Setup metrics monitoring and alerting
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

scheduler.scheduleAtFixedRate(() -> {
    MetricRegistry registry = (MetricRegistry) dataSource.getMetricRegistry();
    String poolName = dataSource.getPoolName();
    
    // Monitor connection acquisition time
    Timer acquisitionTimer = registry.getTimer(poolName + ".pool.Wait");
    double p99AcquisitionTime = acquisitionTimer.getSnapshot().get99thPercentile() / 1000000.0;
    
    if (p99AcquisitionTime > 5000) { // Alert if 99th percentile > 5 seconds
        System.err.println("ALERT: Slow connection acquisition - 99th percentile: " + p99AcquisitionTime + "ms");
    }
    
    // Monitor pool utilization
    Gauge<Integer> totalConnections = registry.getGauge(poolName + ".pool.TotalConnections");
    Gauge<Integer> activeConnections = registry.getGauge(poolName + ".pool.ActiveConnections");
    
    if (totalConnections.getValue() > 0) {
        double utilization = (double) activeConnections.getValue() / totalConnections.getValue();
        if (utilization > 0.9) { // Alert if utilization > 90%
            System.err.println("ALERT: High pool utilization: " + String.format("%.1f%%", utilization * 100));
        }
    }
    
    // Monitor pending connections
    Gauge<Integer> pendingConnections = registry.getGauge(poolName + ".pool.PendingConnections");
    if (pendingConnections.getValue() > 5) {
        System.err.println("ALERT: High pending connections: " + pendingConnections.getValue());
    }
    
}, 30, 30, TimeUnit.SECONDS);

Install with Tessl CLI

npx tessl i tessl/maven-com-zaxxer--hikari-cp-java6

docs

configuration.md

hibernate-integration.md

index.md

jmx-management.md

metrics-monitoring.md

utilities-advanced.md

tile.json