Skip to content

Commit

Permalink
Merge branch 'dropwizard5-metrics' of https://github.com/wholesail/Hi…
Browse files Browse the repository at this point in the history
…kariCP into wholesail-dropwizard5-metrics
  • Loading branch information
brettwooldridge committed Nov 2, 2024
2 parents 84a140c + 3f377c0 commit fb49f35
Show file tree
Hide file tree
Showing 14 changed files with 819 additions and 304 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Changes in 6.0.1

* change default maxLifetime variance from 2.5% to 25% to further avoid mass connection die-off dips

* Dropwizard 5 metrics are now supported via the setMetricRegistry() method in HikariConfig and in HikariDataSource

Changes in 6.0.0

* fixed #2152 duplicate connection in try with resources clause caused close() being called twice on each connection
Expand Down
11 changes: 10 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@

<docker.maven.plugin.fabric8.version>0.45.0</docker.maven.plugin.fabric8.version>
<felix.bundle.plugin.version>5.1.1</felix.bundle.plugin.version>
<felix.version>6.0.1</felix.version>
<felix.version>7.0.5</felix.version>
<hibernate.version>5.4.24.Final</hibernate.version>
<javassist.version>3.29.2-GA</javassist.version>
<jndi.version>0.11.4.1</jndi.version>
<maven.release.version>3.0.1</maven.release.version>
<metrics.version>3.2.5</metrics.version>
<metrics5.version>5.0.0-rc17</metrics5.version>
<micrometer.version>1.5.10</micrometer.version>
<simpleclient.version>0.16.0</simpleclient.version>
<mockito.version>3.7.7</mockito.version>
Expand Down Expand Up @@ -195,6 +196,13 @@
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics5</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics5.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
Expand Down Expand Up @@ -581,6 +589,7 @@
javax.sql.rowset.spi,
com.codahale.metrics;resolution:=optional,
com.codahale.metrics.health;resolution:=optional,
io.dropwizard.metrics5;resolution:=optional,
io.micrometer.core.instrument;resolution:=optional,
org.slf4j;version="[1.6,2)",
org.hibernate;resolution:=optional,
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/zaxxer/hikari/HikariConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,10 @@ public void setMetricRegistry(Object metricRegistry)
metricRegistry = getObjectOrPerformJndiLookup(metricRegistry);

if (!safeIsAssignableFrom(metricRegistry, "com.codahale.metrics.MetricRegistry")
&& !(safeIsAssignableFrom(metricRegistry, "io.dropwizard.metrics5.MetricRegistry"))
&& !(safeIsAssignableFrom(metricRegistry, "io.micrometer.core.instrument.MeterRegistry"))) {
throw new IllegalArgumentException("Class must be instance of com.codahale.metrics.MetricRegistry or io.micrometer.core.instrument.MeterRegistry");
throw new IllegalArgumentException("Class must be instance of com.codahale.metrics.MetricRegistry, " +
"io.dropwizard.metrics5.MetricRegistry, or io.micrometer.core.instrument.MeterRegistry");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.PoolStats;

import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_CATEGORY;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_ACTIVE_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_CONNECT;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_IDLE_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_MAX_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_MIN_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_PENDING_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_TIMEOUT_RATE;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_TOTAL_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_USAGE;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_WAIT;

public final class CodaHaleMetricsTracker implements IMetricsTracker
{
private final String poolName;
Expand All @@ -35,18 +47,6 @@ public final class CodaHaleMetricsTracker implements IMetricsTracker
private final Meter connectionTimeoutMeter;
private final MetricRegistry registry;

private static final String METRIC_CATEGORY = "pool";
private static final String METRIC_NAME_WAIT = "Wait";
private static final String METRIC_NAME_USAGE = "Usage";
private static final String METRIC_NAME_CONNECT = "ConnectionCreation";
private static final String METRIC_NAME_TIMEOUT_RATE = "ConnectionTimeoutRate";
private static final String METRIC_NAME_TOTAL_CONNECTIONS = "TotalConnections";
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";

CodaHaleMetricsTracker(final String poolName, final PoolStats poolStats, final MetricRegistry registry)
{
this.poolName = poolName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package com.zaxxer.hikari.metrics.dropwizard;

import java.util.concurrent.TimeUnit;

import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.PoolStats;
import io.dropwizard.metrics5.Gauge;
import io.dropwizard.metrics5.Histogram;
import io.dropwizard.metrics5.Meter;
import io.dropwizard.metrics5.MetricRegistry;
import io.dropwizard.metrics5.Timer;

import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_CATEGORY;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_ACTIVE_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_CONNECT;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_IDLE_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_MAX_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_MIN_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_PENDING_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_TIMEOUT_RATE;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_TOTAL_CONNECTIONS;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_USAGE;
import static com.zaxxer.hikari.metrics.dropwizard.DropwizardCommon.METRIC_NAME_WAIT;

public class Dropwizard5MetricsTracker implements IMetricsTracker
{
private final String poolName;
private final Timer connectionObtainTimer;
private final Histogram connectionUsage;
private final Histogram connectionCreation;
private final Meter connectionTimeoutMeter;
private final MetricRegistry registry;

Dropwizard5MetricsTracker(final String poolName, final PoolStats poolStats, final MetricRegistry registry)
{
this.poolName = poolName;
this.registry = registry;
this.connectionObtainTimer = registry.timer(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_WAIT));
this.connectionUsage = registry.histogram(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_USAGE));
this.connectionCreation = registry.histogram(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_CONNECT));
this.connectionTimeoutMeter = registry.meter(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_TIMEOUT_RATE));

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_TOTAL_CONNECTIONS),
(Gauge<Integer>) poolStats::getTotalConnections);

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_IDLE_CONNECTIONS),
(Gauge<Integer>) poolStats::getIdleConnections);

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_ACTIVE_CONNECTIONS),
(Gauge<Integer>) poolStats::getActiveConnections);

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_PENDING_CONNECTIONS),
(Gauge<Integer>) poolStats::getPendingThreads);

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MAX_CONNECTIONS),
(Gauge<Integer>) poolStats::getMaxConnections);

registry.register(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_MIN_CONNECTIONS),
(Gauge<Integer>) poolStats::getMinConnections);
}

/** {@inheritDoc} */
@Override
public void close()
{
registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_WAIT));
registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_USAGE));
registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_CONNECT));
registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_TIMEOUT_RATE));
registry.remove(MetricRegistry.name(poolName, METRIC_CATEGORY, METRIC_NAME_TOTAL_CONNECTIONS));
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} */
@Override
public void recordConnectionAcquiredNanos(final long elapsedAcquiredNanos)
{
connectionObtainTimer.update(elapsedAcquiredNanos, TimeUnit.NANOSECONDS);
}

/** {@inheritDoc} */
@Override
public void recordConnectionUsageMillis(final long elapsedBorrowedMillis)
{
connectionUsage.update(elapsedBorrowedMillis);
}

@Override
public void recordConnectionTimeout()
{
connectionTimeoutMeter.mark();
}

@Override
public void recordConnectionCreatedMillis(final long connectionCreatedMillis)
{
connectionCreation.update(connectionCreatedMillis);
}

public Timer getConnectionAcquisitionTimer()
{
return connectionObtainTimer;
}

public Histogram getConnectionDurationHistogram()
{
return connectionUsage;
}

public Histogram getConnectionCreationHistogram()
{
return connectionCreation;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.zaxxer.hikari.metrics.dropwizard;

import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.metrics.PoolStats;
import io.dropwizard.metrics5.MetricRegistry;

public class Dropwizard5MetricsTrackerFactory implements MetricsTrackerFactory
{
private final MetricRegistry registry;

public Dropwizard5MetricsTrackerFactory(final MetricRegistry registry)
{
this.registry = registry;
}

public MetricRegistry getRegistry()
{
return registry;
}

@Override
public IMetricsTracker create(final String poolName, final PoolStats poolStats)
{
return new Dropwizard5MetricsTracker(poolName, poolStats, registry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.zaxxer.hikari.metrics.dropwizard;

final class DropwizardCommon {
private DropwizardCommon()
{
}

static final String METRIC_CATEGORY = "pool";
static final String METRIC_NAME_WAIT = "Wait";
static final String METRIC_NAME_USAGE = "Usage";
static final String METRIC_NAME_CONNECT = "ConnectionCreation";
static final String METRIC_NAME_TIMEOUT_RATE = "ConnectionTimeoutRate";
static final String METRIC_NAME_TOTAL_CONNECTIONS = "TotalConnections";
static final String METRIC_NAME_IDLE_CONNECTIONS = "IdleConnections";
static final String METRIC_NAME_ACTIVE_CONNECTIONS = "ActiveConnections";
static final String METRIC_NAME_PENDING_CONNECTIONS = "PendingConnections";
static final String METRIC_NAME_MAX_CONNECTIONS = "MaxConnections";
static final String METRIC_NAME_MIN_CONNECTIONS = "MinConnections";
}
4 changes: 4 additions & 0 deletions src/main/java/com/zaxxer/hikari/pool/HikariPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.zaxxer.hikari.metrics.PoolStats;
import com.zaxxer.hikari.metrics.dropwizard.CodahaleHealthChecker;
import com.zaxxer.hikari.metrics.dropwizard.CodahaleMetricsTrackerFactory;
import com.zaxxer.hikari.metrics.dropwizard.Dropwizard5MetricsTrackerFactory;
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
import com.zaxxer.hikari.util.ConcurrentBag;
import com.zaxxer.hikari.util.ConcurrentBag.IBagStateListener;
Expand Down Expand Up @@ -288,6 +289,9 @@ public void setMetricRegistry(Object metricRegistry)
if (metricRegistry != null && safeIsAssignableFrom(metricRegistry, "com.codahale.metrics.MetricRegistry")) {
setMetricsTrackerFactory(new CodahaleMetricsTrackerFactory((MetricRegistry) metricRegistry));
}
else if (metricRegistry != null && safeIsAssignableFrom(metricRegistry, "io.dropwizard.metrics5.MetricRegistry")) {
setMetricsTrackerFactory(new Dropwizard5MetricsTrackerFactory((io.dropwizard.metrics5.MetricRegistry) metricRegistry));
}
else if (metricRegistry != null && safeIsAssignableFrom(metricRegistry, "io.micrometer.core.instrument.MeterRegistry")) {
setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory((MeterRegistry) metricRegistry));
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
requires static simpleclient;
requires static metrics.core;
requires static metrics.healthchecks;
requires static io.dropwizard.metrics5;
requires static micrometer.core;
requires static org.javassist;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.zaxxer.hikari.metrics.dropwizard;

import com.zaxxer.hikari.mocks.StubPoolStats;
import io.dropwizard.metrics5.MetricRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class Dropwizard5MetricsTrackerTest
{
@Mock
public MetricRegistry mockMetricRegistry;

private Dropwizard5MetricsTracker testee;

@Before
public void setup()
{
testee = new Dropwizard5MetricsTracker("mypool", new StubPoolStats(0), mockMetricRegistry);
}

@Test
public void close()
{
testee.close();

verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.Wait"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.Usage"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.ConnectionCreation"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.ConnectionTimeoutRate"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.TotalConnections"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.IdleConnections"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.ActiveConnections"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.PendingConnections"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.MaxConnections"));
verify(mockMetricRegistry).remove(MetricRegistry.name("mypool.pool.MinConnections"));
}
}
Loading

0 comments on commit fb49f35

Please sign in to comment.