Commit 470e1d66 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #17504 from ayudovin

* pr/17504:
  Polish "Add metrics support for idle jdbc connections"
  Add metrics support for idle jdbc connections

Closes gh-17504
parents 808b373d 56ce2b8e
......@@ -66,6 +66,7 @@ public class DataSourcePoolMetrics implements MeterBinder {
public void bindTo(MeterRegistry registry) {
if (this.metadataProvider.getDataSourcePoolMetadata(this.dataSource) != null) {
bindPoolMetadata(registry, "active", DataSourcePoolMetadata::getActive);
bindPoolMetadata(registry, "idle", DataSourcePoolMetadata::getIdle);
bindPoolMetadata(registry, "max", DataSourcePoolMetadata::getMax);
bindPoolMetadata(registry, "min", DataSourcePoolMetadata::getMin);
}
......
......@@ -2023,8 +2023,8 @@ is required. A `CacheMetricsRegistrar` bean is made available to make that proce
==== DataSource Metrics
Auto-configuration enables the instrumentation of all available `DataSource` objects with
a metric named `jdbc`. Data source instrumentation results in gauges representing the
currently active, maximum allowed, and minimum allowed connections in the pool. Each of
these gauges has a name that is prefixed by `jdbc`.
currently active, idle, maximum allowed, and minimum allowed connections in the pool. Each
of these gauges has a name that is prefixed by `jdbc`.
Metrics are also tagged by the name of the `DataSource` computed based on the bean name.
......
......@@ -37,6 +37,11 @@ public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMe
return getDataSource().getNumActive();
}
@Override
public Integer getIdle() {
return getDataSource().getNumIdle();
}
@Override
public Integer getMax() {
return getDataSource().getMaxTotal();
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -23,6 +23,7 @@ import javax.sql.DataSource;
* {@link DataSource} implementations.
*
* @author Stephane Nicoll
* @author Artsiom Yudovin
* @since 2.0.0
*/
public interface DataSourcePoolMetadata {
......@@ -49,6 +50,17 @@ public interface DataSourcePoolMetadata {
*/
Integer getActive();
/**
* Return the number of established but idle connections. Can also return {@code null}
* if that information is not available.
* @return the number of established but idle connections or {@code null}
* @since 2.2.0
* @see #getActive()
*/
default Integer getIdle() {
return null;
}
/**
* Return the maximum number of active connections that can be allocated at the same
* time or {@code -1} if there is no limit. Can also return {@code null} if that
......
......@@ -45,6 +45,16 @@ public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
}
}
@Override
public Integer getIdle() {
try {
return getHikariPool().getIdleConnections();
}
catch (Exception ex) {
return null;
}
}
private HikariPool getHikariPool() {
return (HikariPool) new DirectFieldAccessor(getDataSource()).getPropertyValue("pool");
}
......
......@@ -37,6 +37,11 @@ public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
return (pool != null) ? pool.getActive() : 0;
}
@Override
public Integer getIdle() {
return getDataSource().getNumIdle();
}
@Override
public Integer getMax() {
return getDataSource().getMaxActive();
......
......@@ -29,11 +29,13 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @param <D> the data source pool metadata type
* @author Stephane Nicoll
* @author Artsiom Yudovin
*/
abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourcePoolMetadata<?>> {
/**
* Return a data source metadata instance with a min size of 0 and max size of 2.
* Return a data source metadata instance with a min size of 0 and max size of 2. Idle
* connections are not reclaimed immediately.
* @return the data source metadata
*/
protected abstract D getDataSourceMetadata();
......@@ -67,6 +69,13 @@ abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourceP
});
}
@Test
void getIdle() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSourceMetadata().getDataSource());
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
assertThat(getDataSourceMetadata().getIdle()).isEqualTo(Integer.valueOf(1));
}
@Test
void getPoolSizeTwoConnections() {
final JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSourceMetadata().getDataSource());
......
......@@ -83,6 +83,7 @@ class CommonsDbcp2DataSourcePoolMetadataTests
BasicDataSource dataSource = createDataSource();
dataSource.setMinIdle(minSize);
dataSource.setMaxTotal(maxSize);
dataSource.setMinEvictableIdleTimeMillis(5000);
return new CommonsDbcp2DataSourcePoolMetadata(dataSource);
}
......
......@@ -54,6 +54,7 @@ public class HikariDataSourcePoolMetadataTests
HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class).build();
dataSource.setMinimumIdle(minSize);
dataSource.setMaximumPoolSize(maxSize);
dataSource.setIdleTimeout(5000);
return dataSource;
}
......
......@@ -54,6 +54,7 @@ public class TomcatDataSourcePoolMetadataTests
DataSource dataSource = initializeBuilder().type(DataSource.class).build();
dataSource.setMinIdle(minSize);
dataSource.setMaxActive(maxSize);
dataSource.setMinEvictableIdleTimeMillis(5000);
// Avoid warnings
dataSource.setInitialSize(minSize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment