Expose metrics through the HikariDataSource.

pull/158/head
Brett Wooldridge 11 years ago
parent a96ce54349
commit 83b2a6939b

@ -29,6 +29,7 @@ import javax.sql.DataSource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.pool.HikariPool; import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy; import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
import com.zaxxer.hikari.util.DriverDataSource; import com.zaxxer.hikari.util.DriverDataSource;
@ -215,6 +216,18 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
} }
} }
/**
* Get the metrics tracker associated with this DataSource. If metrics collection is
* disabled, the resulting object will provide no meaning data or return null from
* some APIs.
*
* @return the metrics tracker for this DataSource
*/
public IMetricsTracker getMetricsTracker()
{
return (pool != null ? pool.getMetricsTracker() : null);
}
/** /**
* <code>close()</code> and <code>shutdown()</code> are synonymous. * <code>close()</code> and <code>shutdown()</code> are synonymous.
*/ */

@ -24,31 +24,45 @@ import com.zaxxer.hikari.pool.HikariPool;
public final class CodaHaleMetricsTracker extends MetricsTracker public final class CodaHaleMetricsTracker extends MetricsTracker
{ {
private MetricRegistry registry; private MetricRegistry registry;
private Timer connectionObtainTimer; private final Timer connectionObtainTimer;
private Histogram connectionUsage; private final Histogram connectionUsage;
public CodaHaleMetricsTracker(String poolName) public CodaHaleMetricsTracker(final HikariPool pool)
{ {
super(pool);
registry = new MetricRegistry(); registry = new MetricRegistry();
connectionObtainTimer = registry.timer(MetricRegistry.name(HikariPool.class, "connection", "wait")); connectionObtainTimer = registry.timer(MetricRegistry.name(HikariPool.class, pool.getConfiguration().getPoolName() + "-connection", "wait"));
connectionUsage = registry.histogram(MetricRegistry.name(HikariPool.class, "connection", "usage")); connectionUsage = registry.histogram(MetricRegistry.name(HikariPool.class, pool.getConfiguration().getPoolName() + "-connection", "usage"));
} }
/** {@inheritDoc} */
@Override @Override
public Context recordConnectionRequest(long requestTime) public Context recordConnectionRequest(long requestTime)
{ {
return new Context(connectionObtainTimer); return new Context(connectionObtainTimer);
} }
/** {@inheritDoc} */
@Override @Override
public void recordConnectionUsage(long usageMilleseconds) public void recordConnectionUsage(long usageMilleseconds)
{ {
connectionUsage.update(usageMilleseconds); connectionUsage.update(usageMilleseconds);
} }
public Timer getConnectionAcquisitionTimer()
{
return connectionObtainTimer;
}
public Histogram getConnectionDurationHistogram()
{
return connectionUsage;
}
public static final class Context extends MetricsContext public static final class Context extends MetricsContext
{ {
Timer.Context innerContext; final Timer.Context innerContext;
Context(Timer timer) Context(Timer timer)
{ {

@ -30,7 +30,7 @@ public interface IMetricsTracker
* @param startTime the timestamp of the start time as returned by System.currentTimeMillis() * @param startTime the timestamp of the start time as returned by System.currentTimeMillis()
* @return an instance of MetricsContext * @return an instance of MetricsContext
*/ */
public MetricsContext recordConnectionRequest(long startTime); MetricsContext recordConnectionRequest(long startTime);
/** /**
* This method is called when a Connection is closed, with the total time in milliseconds * This method is called when a Connection is closed, with the total time in milliseconds
@ -38,7 +38,35 @@ public interface IMetricsTracker
* *
* @param usageMilleseconds the Connection usage time in milliseconds * @param usageMilleseconds the Connection usage time in milliseconds
*/ */
public void recordConnectionUsage(long usageMilleseconds); void recordConnectionUsage(long usageMilleseconds);
/**
* Get the current number of idle connections.
*
* @return the number of idle connections in the pool
*/
int getIdleConnections();
/**
* Get the current number of active (in-use) connections.
*
* @return the number of active connections in the pool
*/
int getActiveConnections();
/**
* Get the current total number of connections.
*
* @return the total number of connections in the pool
*/
int getTotalConnections();
/**
* Get the current number of threads awaiting a connection.
*
* @return the number of awaiting threads
*/
int getThreadsAwaitingConnection();
/** /**
* A base instance of a MetricsContext. Classes extending this class should exhibit the * A base instance of a MetricsContext. Classes extending this class should exhibit the

@ -16,6 +16,7 @@
package com.zaxxer.hikari.metrics; package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.util.PoolUtilities; import com.zaxxer.hikari.util.PoolUtilities;
/** /**
@ -29,8 +30,8 @@ public final class MetricsFactory
// private contructor // private contructor
} }
public static final IMetricsTracker createMetricsTracker(String metricsClassName, String poolName) public static final IMetricsTracker createMetricsTracker(String metricsClassName, HikariPool pool)
{ {
return PoolUtilities.createInstance(metricsClassName, IMetricsTracker.class, poolName); return PoolUtilities.createInstance(metricsClassName, IMetricsTracker.class, pool);
} }
} }

@ -16,8 +16,10 @@
package com.zaxxer.hikari.metrics; package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
/** /**
* This class does absolutely nothing. * This class only supports realtime, not historical metrics.
* *
* @author Brett Wooldridge * @author Brett Wooldridge
*/ */
@ -25,20 +27,51 @@ public class MetricsTracker implements IMetricsTracker
{ {
public static final MetricsContext NO_CONTEXT = new MetricsContext(); public static final MetricsContext NO_CONTEXT = new MetricsContext();
public MetricsTracker() protected final HikariPool pool;
{
}
public MetricsTracker(String poolName) public MetricsTracker(final HikariPool pool)
{ {
this.pool = pool;
} }
/** {@inheritDoc} */
@Override
public MetricsContext recordConnectionRequest(long requestTime) public MetricsContext recordConnectionRequest(long requestTime)
{ {
return NO_CONTEXT; return NO_CONTEXT;
} }
/** {@inheritDoc} */
@Override
public void recordConnectionUsage(long usageMilleseconds) public void recordConnectionUsage(long usageMilleseconds)
{ {
} }
/** {@inheritDoc} */
@Override
public int getIdleConnections()
{
return pool.getIdleConnections();
}
/** {@inheritDoc} */
@Override
public int getActiveConnections()
{
return pool.getActiveConnections();
}
/** {@inheritDoc} */
@Override
public int getTotalConnections()
{
return pool.getTotalConnections();
}
/** {@inheritDoc} */
@Override
public int getThreadsAwaitingConnection()
{
return pool.getThreadsAwaitingConnection();
}
} }

@ -134,7 +134,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
this.transactionIsolation = PoolUtilities.getTransactionIsolation(configuration.getTransactionIsolation()); this.transactionIsolation = PoolUtilities.getTransactionIsolation(configuration.getTransactionIsolation());
this.isRecordMetrics = configuration.isRecordMetrics(); this.isRecordMetrics = configuration.isRecordMetrics();
this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName() this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName()
: "com.zaxxer.hikari.metrics.MetricsTracker"), configuration.getPoolName()); : "com.zaxxer.hikari.metrics.MetricsTracker"), this);
this.dataSource = initializeDataSource(); this.dataSource = initializeDataSource();
@ -275,6 +275,26 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
return dataSource; return dataSource;
} }
/**
* Get the pool configuration object.
*
* @return the {@link HikariConfig} for this pool
*/
public HikariConfig getConfiguration()
{
return configuration;
}
/**
* Get the metrics tracker for this pool.
*
* @return the metrics tracker
*/
public IMetricsTracker getMetricsTracker()
{
return metricsTracker;
}
@Override @Override
public String toString() public String toString()
{ {

@ -29,6 +29,7 @@ import javax.sql.DataSource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.pool.HikariPool; import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy; import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
import com.zaxxer.hikari.util.DriverDataSource; import com.zaxxer.hikari.util.DriverDataSource;
@ -215,6 +216,18 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
} }
} }
/**
* Get the metrics tracker associated with this DataSource. If metrics collection is
* disabled, the resulting object will provide no meaning data or return null from
* some APIs.
*
* @return the metrics tracker for this DataSource
*/
public IMetricsTracker getMetricsTracker()
{
return (pool != null ? pool.getMetricsTracker() : null);
}
/** /**
* <code>close()</code> and <code>shutdown()</code> are synonymous. * <code>close()</code> and <code>shutdown()</code> are synonymous.
*/ */

@ -27,25 +27,39 @@ public final class CodaHaleMetricsTracker extends MetricsTracker
private final Timer connectionObtainTimer; private final Timer connectionObtainTimer;
private final Histogram connectionUsage; private final Histogram connectionUsage;
public CodaHaleMetricsTracker(String poolName) public CodaHaleMetricsTracker(final HikariPool pool)
{ {
super(pool);
registry = new MetricRegistry(); registry = new MetricRegistry();
connectionObtainTimer = registry.timer(MetricRegistry.name(HikariPool.class, poolName + "-connection", "wait")); connectionObtainTimer = registry.timer(MetricRegistry.name(HikariPool.class, pool.getConfiguration().getPoolName() + "-connection", "wait"));
connectionUsage = registry.histogram(MetricRegistry.name(HikariPool.class, poolName + "-connection", "usage")); connectionUsage = registry.histogram(MetricRegistry.name(HikariPool.class, pool.getConfiguration().getPoolName() + "-connection", "usage"));
} }
/** {@inheritDoc} */
@Override @Override
public Context recordConnectionRequest(long requestTime) public Context recordConnectionRequest(long requestTime)
{ {
return new Context(connectionObtainTimer); return new Context(connectionObtainTimer);
} }
/** {@inheritDoc} */
@Override @Override
public void recordConnectionUsage(long usageMilleseconds) public void recordConnectionUsage(long usageMilleseconds)
{ {
connectionUsage.update(usageMilleseconds); connectionUsage.update(usageMilleseconds);
} }
public Timer getConnectionAcquisitionTimer()
{
return connectionObtainTimer;
}
public Histogram getConnectionDurationHistogram()
{
return connectionUsage;
}
public static final class Context extends MetricsContext public static final class Context extends MetricsContext
{ {
final Timer.Context innerContext; final Timer.Context innerContext;

@ -30,7 +30,7 @@ public interface IMetricsTracker
* @param startTime the timestamp of the start time as returned by System.currentTimeMillis() * @param startTime the timestamp of the start time as returned by System.currentTimeMillis()
* @return an instance of MetricsContext * @return an instance of MetricsContext
*/ */
public MetricsContext recordConnectionRequest(long startTime); MetricsContext recordConnectionRequest(long startTime);
/** /**
* This method is called when a Connection is closed, with the total time in milliseconds * This method is called when a Connection is closed, with the total time in milliseconds
@ -38,7 +38,35 @@ public interface IMetricsTracker
* *
* @param usageMilleseconds the Connection usage time in milliseconds * @param usageMilleseconds the Connection usage time in milliseconds
*/ */
public void recordConnectionUsage(long usageMilleseconds); void recordConnectionUsage(long usageMilleseconds);
/**
* Get the current number of idle connections.
*
* @return the number of idle connections in the pool
*/
int getIdleConnections();
/**
* Get the current number of active (in-use) connections.
*
* @return the number of active connections in the pool
*/
int getActiveConnections();
/**
* Get the current total number of connections.
*
* @return the total number of connections in the pool
*/
int getTotalConnections();
/**
* Get the current number of threads awaiting a connection.
*
* @return the number of awaiting threads
*/
int getThreadsAwaitingConnection();
/** /**
* A base instance of a MetricsContext. Classes extending this class should exhibit the * A base instance of a MetricsContext. Classes extending this class should exhibit the

@ -16,6 +16,7 @@
package com.zaxxer.hikari.metrics; package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.util.PoolUtilities; import com.zaxxer.hikari.util.PoolUtilities;
/** /**
@ -29,8 +30,8 @@ public final class MetricsFactory
// private contructor // private contructor
} }
public static final IMetricsTracker createMetricsTracker(String metricsClassName, String poolName) public static final IMetricsTracker createMetricsTracker(String metricsClassName, HikariPool pool)
{ {
return PoolUtilities.createInstance(metricsClassName, IMetricsTracker.class, poolName); return PoolUtilities.createInstance(metricsClassName, IMetricsTracker.class, pool);
} }
} }

@ -16,8 +16,10 @@
package com.zaxxer.hikari.metrics; package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
/** /**
* This class does absolutely nothing. * This class only supports realtime, not historical metrics.
* *
* @author Brett Wooldridge * @author Brett Wooldridge
*/ */
@ -25,20 +27,51 @@ public class MetricsTracker implements IMetricsTracker
{ {
public static final MetricsContext NO_CONTEXT = new MetricsContext(); public static final MetricsContext NO_CONTEXT = new MetricsContext();
public MetricsTracker() protected final HikariPool pool;
{
}
public MetricsTracker(String poolName) public MetricsTracker(final HikariPool pool)
{ {
this.pool = pool;
} }
/** {@inheritDoc} */
@Override
public MetricsContext recordConnectionRequest(long requestTime) public MetricsContext recordConnectionRequest(long requestTime)
{ {
return NO_CONTEXT; return NO_CONTEXT;
} }
/** {@inheritDoc} */
@Override
public void recordConnectionUsage(long usageMilleseconds) public void recordConnectionUsage(long usageMilleseconds)
{ {
} }
/** {@inheritDoc} */
@Override
public int getIdleConnections()
{
return pool.getIdleConnections();
}
/** {@inheritDoc} */
@Override
public int getActiveConnections()
{
return pool.getActiveConnections();
}
/** {@inheritDoc} */
@Override
public int getTotalConnections()
{
return pool.getTotalConnections();
}
/** {@inheritDoc} */
@Override
public int getThreadsAwaitingConnection()
{
return pool.getThreadsAwaitingConnection();
}
} }

@ -133,7 +133,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
this.transactionIsolation = PoolUtilities.getTransactionIsolation(configuration.getTransactionIsolation()); this.transactionIsolation = PoolUtilities.getTransactionIsolation(configuration.getTransactionIsolation());
this.isRecordMetrics = configuration.isRecordMetrics(); this.isRecordMetrics = configuration.isRecordMetrics();
this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName() this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName()
: "com.zaxxer.hikari.metrics.MetricsTracker"), configuration.getPoolName()); : "com.zaxxer.hikari.metrics.MetricsTracker"), this);
this.dataSource = initializeDataSource(); this.dataSource = initializeDataSource();
@ -143,7 +143,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
addConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection filler", configuration.getThreadFactory()); addConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection filler", configuration.getThreadFactory());
closeConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection closer", configuration.getThreadFactory()); closeConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection closer", configuration.getThreadFactory());
fillPool(); fillPool();
long delayPeriod = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", TimeUnit.SECONDS.toMillis(30L)); long delayPeriod = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", TimeUnit.SECONDS.toMillis(30L));
@ -272,6 +272,26 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
return dataSource; return dataSource;
} }
/**
* Get the pool configuration object.
*
* @return the {@link HikariConfig} for this pool
*/
public HikariConfig getConfiguration()
{
return configuration;
}
/**
* Get the metrics tracker for this pool.
*
* @return the metrics tracker
*/
public IMetricsTracker getMetricsTracker()
{
return metricsTracker;
}
@Override @Override
public String toString() public String toString()
{ {

Loading…
Cancel
Save