com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTracker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of HikariCP Show documentation
Show all versions of HikariCP Show documentation
Ultimate JDBC Connection Pool
package com.zaxxer.hikari.metrics.micrometer;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.PoolStats;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import java.util.concurrent.TimeUnit;
/**
* {@link IMetricsTracker Metrics tracker} for Micrometer.
* HikariCP metrics can be configured in your application by applying a
* {@link io.micrometer.core.instrument.config.MeterFilter MeterFilter} to metrics starting with
* {@link #HIKARI_METRIC_NAME_PREFIX}. For example, to configure client-side calculated percentiles:
*
*
* new MeterFilter() {
* @Override
* public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
* if (id.getName().startsWith(MicrometerMetricsTracker.HIKARI_METRIC_NAME_PREFIX)) {
* return DistributionStatisticConfig.builder()
* .percentiles(0.5, 0.95)
* .build()
* .merge(config);
* }
* return config;
* }
* };
*
*/
public class MicrometerMetricsTracker implements IMetricsTracker
{
/** Prefix used for all HikariCP metric names. */
public static final String HIKARI_METRIC_NAME_PREFIX = "hikaricp";
private static final String METRIC_CATEGORY = "pool";
private static final String METRIC_NAME_WAIT = HIKARI_METRIC_NAME_PREFIX + ".connections.acquire";
private static final String METRIC_NAME_USAGE = HIKARI_METRIC_NAME_PREFIX + ".connections.usage";
private static final String METRIC_NAME_CONNECT = HIKARI_METRIC_NAME_PREFIX + ".connections.creation";
private static final String METRIC_NAME_TIMEOUT_RATE = HIKARI_METRIC_NAME_PREFIX + ".connections.timeout";
private static final String METRIC_NAME_TOTAL_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections";
private static final String METRIC_NAME_IDLE_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.idle";
private static final String METRIC_NAME_ACTIVE_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.active";
private static final String METRIC_NAME_PENDING_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.pending";
private static final String METRIC_NAME_MAX_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.max";
private static final String METRIC_NAME_MIN_CONNECTIONS = HIKARI_METRIC_NAME_PREFIX + ".connections.min";
private final Timer connectionObtainTimer;
private final Counter connectionTimeoutCounter;
private final Timer connectionUsage;
private final Timer connectionCreation;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge totalConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge idleConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge activeConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge pendingConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge maxConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final Gauge minConnectionGauge;
@SuppressWarnings("FieldCanBeLocal")
private final MeterRegistry meterRegistry;
@SuppressWarnings("FieldCanBeLocal")
private final PoolStats poolStats;
MicrometerMetricsTracker(final String poolName, final PoolStats poolStats, final MeterRegistry meterRegistry)
{
// poolStats must be held with a 'strong reference' even though it is never referenced within this class
this.poolStats = poolStats; // DO NOT REMOVE
this.meterRegistry = meterRegistry;
this.connectionObtainTimer = Timer.builder(METRIC_NAME_WAIT)
.description("Connection acquire time")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.connectionCreation = Timer.builder(METRIC_NAME_CONNECT)
.description("Connection creation time")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.connectionUsage = Timer.builder(METRIC_NAME_USAGE)
.description("Connection usage time")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.connectionTimeoutCounter = Counter.builder(METRIC_NAME_TIMEOUT_RATE)
.description("Connection timeout total count")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.totalConnectionGauge = Gauge.builder(METRIC_NAME_TOTAL_CONNECTIONS, poolStats, PoolStats::getTotalConnections)
.description("Total connections")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.idleConnectionGauge = Gauge.builder(METRIC_NAME_IDLE_CONNECTIONS, poolStats, PoolStats::getIdleConnections)
.description("Idle connections")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.activeConnectionGauge = Gauge.builder(METRIC_NAME_ACTIVE_CONNECTIONS, poolStats, PoolStats::getActiveConnections)
.description("Active connections")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.pendingConnectionGauge = Gauge.builder(METRIC_NAME_PENDING_CONNECTIONS, poolStats, PoolStats::getPendingThreads)
.description("Pending threads")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.maxConnectionGauge = Gauge.builder(METRIC_NAME_MAX_CONNECTIONS, poolStats, PoolStats::getMaxConnections)
.description("Max connections")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
this.minConnectionGauge = Gauge.builder(METRIC_NAME_MIN_CONNECTIONS, poolStats, PoolStats::getMinConnections)
.description("Min connections")
.tags(METRIC_CATEGORY, poolName)
.register(meterRegistry);
}
/** {@inheritDoc} */
@Override
public void recordConnectionAcquiredNanos(final long elapsedAcquiredNanos)
{
connectionObtainTimer.record(elapsedAcquiredNanos, TimeUnit.NANOSECONDS);
}
/** {@inheritDoc} */
@Override
public void recordConnectionUsageMillis(final long elapsedBorrowedMillis)
{
connectionUsage.record(elapsedBorrowedMillis, TimeUnit.MILLISECONDS);
}
@Override
public void recordConnectionTimeout()
{
connectionTimeoutCounter.increment();
}
@Override
public void recordConnectionCreatedMillis(long connectionCreatedMillis)
{
connectionCreation.record(connectionCreatedMillis, TimeUnit.MILLISECONDS);
}
@Override
public void close() {
meterRegistry.remove(connectionObtainTimer);
meterRegistry.remove(connectionTimeoutCounter);
meterRegistry.remove(connectionUsage);
meterRegistry.remove(connectionCreation);
meterRegistry.remove(totalConnectionGauge);
meterRegistry.remove(idleConnectionGauge);
meterRegistry.remove(activeConnectionGauge);
meterRegistry.remove(pendingConnectionGauge);
meterRegistry.remove(maxConnectionGauge);
meterRegistry.remove(minConnectionGauge);
}
}