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.LoggerFactory;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
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.
*/

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

@ -30,7 +30,7 @@ public interface IMetricsTracker
* @param startTime the timestamp of the start time as returned by System.currentTimeMillis()
* @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
@ -38,7 +38,35 @@ public interface IMetricsTracker
*
* @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

@ -16,6 +16,7 @@
package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.util.PoolUtilities;
/**
@ -29,8 +30,8 @@ public final class MetricsFactory
// 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;
import com.zaxxer.hikari.pool.HikariPool;
/**
* This class does absolutely nothing.
* This class only supports realtime, not historical metrics.
*
* @author Brett Wooldridge
*/
@ -25,20 +27,51 @@ public class MetricsTracker implements IMetricsTracker
{
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)
{
return NO_CONTEXT;
}
/** {@inheritDoc} */
@Override
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.isRecordMetrics = configuration.isRecordMetrics();
this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName()
: "com.zaxxer.hikari.metrics.MetricsTracker"), configuration.getPoolName());
: "com.zaxxer.hikari.metrics.MetricsTracker"), this);
this.dataSource = initializeDataSource();
@ -275,6 +275,26 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
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
public String toString()
{

@ -29,6 +29,7 @@ import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
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.
*/

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

@ -30,7 +30,7 @@ public interface IMetricsTracker
* @param startTime the timestamp of the start time as returned by System.currentTimeMillis()
* @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
@ -38,7 +38,35 @@ public interface IMetricsTracker
*
* @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

@ -16,6 +16,7 @@
package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.util.PoolUtilities;
/**
@ -29,8 +30,8 @@ public final class MetricsFactory
// 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;
import com.zaxxer.hikari.pool.HikariPool;
/**
* This class does absolutely nothing.
* This class only supports realtime, not historical metrics.
*
* @author Brett Wooldridge
*/
@ -25,20 +27,51 @@ public class MetricsTracker implements IMetricsTracker
{
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)
{
return NO_CONTEXT;
}
/** {@inheritDoc} */
@Override
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.isRecordMetrics = configuration.isRecordMetrics();
this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName()
: "com.zaxxer.hikari.metrics.MetricsTracker"), configuration.getPoolName());
: "com.zaxxer.hikari.metrics.MetricsTracker"), this);
this.dataSource = initializeDataSource();
@ -143,7 +143,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
addConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection filler", configuration.getThreadFactory());
closeConnectionExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection closer", configuration.getThreadFactory());
fillPool();
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;
}
/**
* 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
public String toString()
{

Loading…
Cancel
Save