From 3313174891b6f04e8a35521c17f69eab27fdc8e7 Mon Sep 17 00:00:00 2001 From: Manabu Matsuzaki Date: Fri, 16 Mar 2018 02:31:56 +0900 Subject: [PATCH] Add pool metrics (#1110) --- .../com/zaxxer/hikari/metrics/PoolStats.java | 20 ++++++++++++++++++- .../dropwizard/CodaHaleMetricsTracker.java | 20 +++++++++++++++++++ .../micrometer/MicrometerMetricsTracker.java | 16 +++++++++++++++ .../metrics/prometheus/HikariCPCollector.java | 6 +++++- .../com/zaxxer/hikari/pool/HikariPool.java | 2 ++ .../CodaHaleMetricsTrackerTest.java | 2 ++ .../prometheus/HikariCPCollectorTest.java | 8 ++++++++ 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/metrics/PoolStats.java b/src/main/java/com/zaxxer/hikari/metrics/PoolStats.java index e8905d10..b5b85367 100644 --- a/src/main/java/com/zaxxer/hikari/metrics/PoolStats.java +++ b/src/main/java/com/zaxxer/hikari/metrics/PoolStats.java @@ -34,13 +34,15 @@ public abstract class PoolStats protected volatile int idleConnections; protected volatile int activeConnections; protected volatile int pendingThreads; + protected volatile int maxConnections; + protected volatile int minConnections; public PoolStats(final long timeoutMs) { this.timeoutMs = timeoutMs; this.reloadAt = new AtomicLong(); } - + public int getTotalConnections() { if (shouldLoad()) { @@ -77,6 +79,22 @@ public abstract class PoolStats return pendingThreads; } + public int getMaxConnections() { + if (shouldLoad()) { + update(); + } + + return maxConnections; + } + + public int getMinConnections() { + if (shouldLoad()) { + update(); + } + + return minConnections; + } + protected abstract void update(); private boolean shouldLoad() diff --git a/src/main/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTracker.java b/src/main/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTracker.java index 5be5e230..ba0ee804 100644 --- a/src/main/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTracker.java +++ b/src/main/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTracker.java @@ -44,6 +44,8 @@ public final class CodaHaleMetricsTracker implements IMetricsTracker private static final String METRIC_NAME_IDLE_CONNECTIONS = "IdleConnections"; private static final String METRIC_NAME_ACTIVE_CONNECTIONS = "ActiveConnections"; private static final String METRIC_NAME_PENDING_CONNECTIONS = "PendingConnections"; + private static final String METRIC_NAME_MAX_CONNECTIONS = "MaxConnections"; + private static final String METRIC_NAME_MIN_CONNECTIONS = "MinConnections"; public CodaHaleMetricsTracker(final String poolName, final PoolStats poolStats, final MetricRegistry registry) { @@ -85,6 +87,22 @@ public final class CodaHaleMetricsTracker implements IMetricsTracker return poolStats.getPendingThreads(); } }); + + registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MAX_CONNECTIONS), + new Gauge() { + @Override + public Integer getValue() { + return poolStats.getMaxConnections(); + } + }); + + registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MIN_CONNECTIONS), + new Gauge() { + @Override + public Integer getValue() { + return poolStats.getMinConnections(); + } + }); } /** {@inheritDoc} */ @@ -99,6 +117,8 @@ public final class CodaHaleMetricsTracker implements IMetricsTracker registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_IDLE_CONNECTIONS)); registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_ACTIVE_CONNECTIONS)); registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_PENDING_CONNECTIONS)); + registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MAX_CONNECTIONS)); + registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MIN_CONNECTIONS)); } /** {@inheritDoc} */ diff --git a/src/main/java/com/zaxxer/hikari/metrics/micrometer/MicrometerMetricsTracker.java b/src/main/java/com/zaxxer/hikari/metrics/micrometer/MicrometerMetricsTracker.java index f4e44d6e..4d6aeddb 100644 --- a/src/main/java/com/zaxxer/hikari/metrics/micrometer/MicrometerMetricsTracker.java +++ b/src/main/java/com/zaxxer/hikari/metrics/micrometer/MicrometerMetricsTracker.java @@ -21,6 +21,8 @@ public class MicrometerMetricsTracker implements IMetricsTracker private static final String METRIC_NAME_IDLE_CONNECTIONS = "hikaricp.connections.idle"; private static final String METRIC_NAME_ACTIVE_CONNECTIONS = "hikaricp.connections.active"; private static final String METRIC_NAME_PENDING_CONNECTIONS = "hikaricp.connections.pending"; + private static final String METRIC_NAME_MAX_CONNECTIONS = "hikaricp.connections.max"; + private static final String METRIC_NAME_MIN_CONNECTIONS = "hikaricp.connections.min"; private final Timer connectionObtainTimer; private final Counter connectionTimeoutCounter; @@ -35,6 +37,10 @@ public class MicrometerMetricsTracker implements IMetricsTracker @SuppressWarnings({"FieldCanBeLocal", "unused"}) private final Gauge pendingConnectionGauge; @SuppressWarnings({"FieldCanBeLocal", "unused"}) + private final Gauge maxConnectionGauge; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) + private final Gauge minConnectionGauge; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) private final PoolStats poolStats; MicrometerMetricsTracker(final String poolName, final PoolStats poolStats, final MeterRegistry meterRegistry) @@ -84,6 +90,16 @@ public class MicrometerMetricsTracker implements IMetricsTracker .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} */ diff --git a/src/main/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollector.java b/src/main/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollector.java index 3d5fcf0e..41b06836 100644 --- a/src/main/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollector.java +++ b/src/main/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollector.java @@ -42,7 +42,11 @@ class HikariCPCollector extends Collector { createGauge("hikaricp_pending_threads", "Pending threads", PoolStats::getPendingThreads), createGauge("hikaricp_connections", "The number of current connections", - PoolStats::getTotalConnections) + PoolStats::getTotalConnections), + createGauge("hikaricp_max_connections", "Max connections", + PoolStats::getMaxConnections), + createGauge("hikaricp_min_connections", "Min connections", + PoolStats::getMinConnections) ); } diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 36c09fe4..5c194e48 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -638,6 +638,8 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag this.idleConnections = HikariPool.this.getIdleConnections(); this.totalConnections = HikariPool.this.getTotalConnections(); this.activeConnections = HikariPool.this.getActiveConnections(); + this.maxConnections = config.getMaximumPoolSize(); + this.minConnections = config.getMinimumIdle(); } }; } diff --git a/src/test/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTrackerTest.java b/src/test/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTrackerTest.java index 8e2164cc..0da6baef 100644 --- a/src/test/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTrackerTest.java +++ b/src/test/java/com/zaxxer/hikari/metrics/dropwizard/CodaHaleMetricsTrackerTest.java @@ -35,5 +35,7 @@ public class CodaHaleMetricsTrackerTest { verify(mockMetricRegistry).remove("mypool.pool.IdleConnections"); verify(mockMetricRegistry).remove("mypool.pool.ActiveConnections"); verify(mockMetricRegistry).remove("mypool.pool.PendingConnections"); + verify(mockMetricRegistry).remove("mypool.pool.MaxConnections"); + verify(mockMetricRegistry).remove("mypool.pool.MinConnections"); } } diff --git a/src/test/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollectorTest.java b/src/test/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollectorTest.java index 63746a3d..d1c2eaed 100644 --- a/src/test/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollectorTest.java +++ b/src/test/java/com/zaxxer/hikari/metrics/prometheus/HikariCPCollectorTest.java @@ -45,6 +45,8 @@ public class HikariCPCollectorTest { assertThat(getValue("hikaricp_idle_connections", "noConnection"), is(0.0)); assertThat(getValue("hikaricp_pending_threads", "noConnection"), is(0.0)); assertThat(getValue("hikaricp_connections", "noConnection"), is(0.0)); + assertThat(getValue("hikaricp_max_connections", "noConnection"), is(10.0)); + assertThat(getValue("hikaricp_min_connections", "noConnection"), is(0.0)); } finally { StubConnection.slowCreate = false; @@ -65,6 +67,8 @@ public class HikariCPCollectorTest { assertThat(getValue("hikaricp_idle_connections", poolName), is(0.0)); assertThat(getValue("hikaricp_pending_threads", poolName), is(0.0)); assertThat(getValue("hikaricp_connections", poolName), is(0.0)); + assertThat(getValue("hikaricp_max_connections", poolName), is(10.0)); + assertThat(getValue("hikaricp_min_connections", poolName), is(0.0)); } finally { StubConnection.slowCreate = false; @@ -88,6 +92,8 @@ public class HikariCPCollectorTest { assertThat(getValue("hikaricp_idle_connections", "connection1"), is(0.0)); assertThat(getValue("hikaricp_pending_threads", "connection1"), is(0.0)); assertThat(getValue("hikaricp_connections", "connection1"), is(1.0)); + assertThat(getValue("hikaricp_max_connections", "connection1"), is(1.0)); + assertThat(getValue("hikaricp_min_connections", "connection1"), is(1.0)); } finally { StubConnection.slowCreate = false; @@ -111,6 +117,8 @@ public class HikariCPCollectorTest { assertThat(getValue("hikaricp_idle_connections", "connectionClosed"), is(1.0)); assertThat(getValue("hikaricp_pending_threads", "connectionClosed"), is(0.0)); assertThat(getValue("hikaricp_connections", "connectionClosed"), is(1.0)); + assertThat(getValue("hikaricp_max_connections", "connectionClosed"), is(1.0)); + assertThat(getValue("hikaricp_min_connections", "connectionClosed"), is(1.0)); } finally { StubConnection.slowCreate = false;