Skip to content

Commit

Permalink
Adds support for Dropwizard 5 metrics.
Browse files Browse the repository at this point in the history
But not health checks yet, though.
  • Loading branch information
pennello committed Jun 28, 2023
1 parent 07e40c2 commit 3f377c0
Show file tree
Hide file tree
Showing 14 changed files with 821 additions and 303 deletions.
5 changes: 5 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
HikariCP Changes

Changes in 5.0.2

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

Changes in 5.0.0

* rewrote connection elide/add code to fix an unconfirmed but occassionally reported
Expand Down
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<jndi.version>0.11.4.1</jndi.version>
<maven.release.version>2.5.3</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.9.0</simpleclient.version>
<mockito.version>3.7.7</mockito.version>
Expand Down Expand Up @@ -174,6 +175,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 @@ -462,6 +470,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 @@ -671,8 +671,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 @@ -279,6 +280,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 3f377c0

Please sign in to comment.