Commit 9acc02b5 authored by ayudovin's avatar ayudovin Committed by Stephane Nicoll

Add metrics support for idle jdbc connections

See gh-17504
parent 808b373d
...@@ -38,6 +38,7 @@ import org.springframework.util.ConcurrentReferenceHashMap; ...@@ -38,6 +38,7 @@ import org.springframework.util.ConcurrentReferenceHashMap;
* *
* @author Jon Schneider * @author Jon Schneider
* @author Phillip Webb * @author Phillip Webb
* @author Artsiom Yudovin
* @since 2.0.0 * @since 2.0.0
*/ */
public class DataSourcePoolMetrics implements MeterBinder { public class DataSourcePoolMetrics implements MeterBinder {
...@@ -68,6 +69,7 @@ public class DataSourcePoolMetrics implements MeterBinder { ...@@ -68,6 +69,7 @@ public class DataSourcePoolMetrics implements MeterBinder {
bindPoolMetadata(registry, "active", DataSourcePoolMetadata::getActive); bindPoolMetadata(registry, "active", DataSourcePoolMetadata::getActive);
bindPoolMetadata(registry, "max", DataSourcePoolMetadata::getMax); bindPoolMetadata(registry, "max", DataSourcePoolMetadata::getMax);
bindPoolMetadata(registry, "min", DataSourcePoolMetadata::getMin); bindPoolMetadata(registry, "min", DataSourcePoolMetadata::getMin);
bindPoolMetadata(registry, "idle", DataSourcePoolMetadata::getIdle);
} }
} }
......
...@@ -24,6 +24,7 @@ import org.apache.commons.dbcp2.BasicDataSource; ...@@ -24,6 +24,7 @@ import org.apache.commons.dbcp2.BasicDataSource;
* {@link DataSourcePoolMetadata} for an Apache Commons DBCP2 {@link DataSource}. * {@link DataSourcePoolMetadata} for an Apache Commons DBCP2 {@link DataSource}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
* @since 2.0.0 * @since 2.0.0
*/ */
public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<BasicDataSource> { public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<BasicDataSource> {
...@@ -57,4 +58,9 @@ public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMe ...@@ -57,4 +58,9 @@ public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMe
return getDataSource().getDefaultAutoCommit(); return getDataSource().getDefaultAutoCommit();
} }
@Override
public Integer getIdle() {
return getDataSource().getNumIdle();
}
} }
...@@ -23,6 +23,7 @@ import javax.sql.DataSource; ...@@ -23,6 +23,7 @@ import javax.sql.DataSource;
* {@link DataSource} implementations. * {@link DataSource} implementations.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
* @since 2.0.0 * @since 2.0.0
*/ */
public interface DataSourcePoolMetadata { public interface DataSourcePoolMetadata {
...@@ -49,6 +50,16 @@ public interface DataSourcePoolMetadata { ...@@ -49,6 +50,16 @@ public interface DataSourcePoolMetadata {
*/ */
Integer getActive(); 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
*/
default Integer getIdle() {
return null;
}
/** /**
* Return the maximum number of active connections that can be allocated at the same * 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 * time or {@code -1} if there is no limit. Can also return {@code null} if that
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package org.springframework.boot.jdbc.metadata; package org.springframework.boot.jdbc.metadata;
import java.util.Objects;
import javax.sql.DataSource; import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
...@@ -27,6 +29,7 @@ import org.springframework.beans.DirectFieldAccessor; ...@@ -27,6 +29,7 @@ import org.springframework.beans.DirectFieldAccessor;
* {@link DataSourcePoolMetadata} for a Hikari {@link DataSource}. * {@link DataSourcePoolMetadata} for a Hikari {@link DataSource}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
* @since 2.0.0 * @since 2.0.0
*/ */
public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<HikariDataSource> { public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<HikariDataSource> {
...@@ -45,6 +48,16 @@ public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata ...@@ -45,6 +48,16 @@ public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
} }
} }
@Override
public Integer getIdle() {
HikariPool pool = getHikariPool();
if (Objects.nonNull(pool)) {
return pool.getIdleConnections();
}
return null;
}
private HikariPool getHikariPool() { private HikariPool getHikariPool() {
return (HikariPool) new DirectFieldAccessor(getDataSource()).getPropertyValue("pool"); return (HikariPool) new DirectFieldAccessor(getDataSource()).getPropertyValue("pool");
} }
......
...@@ -23,6 +23,7 @@ import org.apache.tomcat.jdbc.pool.DataSource; ...@@ -23,6 +23,7 @@ import org.apache.tomcat.jdbc.pool.DataSource;
* {@link DataSourcePoolMetadata} for a Tomcat DataSource. * {@link DataSourcePoolMetadata} for a Tomcat DataSource.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
* @since 2.0.0 * @since 2.0.0
*/ */
public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<DataSource> { public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<DataSource> {
...@@ -57,4 +58,9 @@ public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata ...@@ -57,4 +58,9 @@ public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
return getDataSource().isDefaultAutoCommit(); return getDataSource().isDefaultAutoCommit();
} }
@Override
public Integer getIdle() {
return getDataSource().getNumIdle();
}
} }
...@@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @param <D> the data source pool metadata type * @param <D> the data source pool metadata type
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
*/ */
abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourcePoolMetadata<?>> { abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourcePoolMetadata<?>> {
...@@ -67,6 +68,11 @@ abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourceP ...@@ -67,6 +68,11 @@ abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourceP
}); });
} }
@Test
void getIdle() {
assertThat(getDataSourceMetadata().getIdle()).isEqualTo(Integer.valueOf(1));
}
@Test @Test
void getPoolSizeTwoConnections() { void getPoolSizeTwoConnections() {
final JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSourceMetadata().getDataSource()); final JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSourceMetadata().getDataSource());
......
...@@ -19,6 +19,9 @@ package org.springframework.boot.jdbc.metadata; ...@@ -19,6 +19,9 @@ package org.springframework.boot.jdbc.metadata;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
...@@ -83,6 +86,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests ...@@ -83,6 +86,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests
BasicDataSource dataSource = createDataSource(); BasicDataSource dataSource = createDataSource();
dataSource.setMinIdle(minSize); dataSource.setMinIdle(minSize);
dataSource.setMaxTotal(maxSize); dataSource.setMaxTotal(maxSize);
this.initPool(dataSource);
return new CommonsDbcp2DataSourcePoolMetadata(dataSource); return new CommonsDbcp2DataSourcePoolMetadata(dataSource);
} }
...@@ -90,4 +96,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests ...@@ -90,4 +96,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests
return initializeBuilder().type(BasicDataSource.class).build(); return initializeBuilder().type(BasicDataSource.class).build();
} }
private void initPool(BasicDataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
}
} }
...@@ -18,12 +18,16 @@ package org.springframework.boot.jdbc.metadata; ...@@ -18,12 +18,16 @@ package org.springframework.boot.jdbc.metadata;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link HikariDataSourcePoolMetadata}. * Tests for {@link HikariDataSourcePoolMetadata}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Artsiom Yudovin
*/ */
public class HikariDataSourcePoolMetadataTests public class HikariDataSourcePoolMetadataTests
extends AbstractDataSourcePoolMetadataTests<HikariDataSourcePoolMetadata> { extends AbstractDataSourcePoolMetadataTests<HikariDataSourcePoolMetadata> {
...@@ -54,7 +58,15 @@ public class HikariDataSourcePoolMetadataTests ...@@ -54,7 +58,15 @@ public class HikariDataSourcePoolMetadataTests
HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class).build(); HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class).build();
dataSource.setMinimumIdle(minSize); dataSource.setMinimumIdle(minSize);
dataSource.setMaximumPoolSize(maxSize); dataSource.setMaximumPoolSize(maxSize);
this.initPool(dataSource);
return dataSource; return dataSource;
} }
private void initPool(HikariDataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
}
} }
...@@ -18,6 +18,9 @@ package org.springframework.boot.jdbc.metadata; ...@@ -18,6 +18,9 @@ package org.springframework.boot.jdbc.metadata;
import org.apache.tomcat.jdbc.pool.DataSource; import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
...@@ -58,7 +61,15 @@ public class TomcatDataSourcePoolMetadataTests ...@@ -58,7 +61,15 @@ public class TomcatDataSourcePoolMetadataTests
// Avoid warnings // Avoid warnings
dataSource.setInitialSize(minSize); dataSource.setInitialSize(minSize);
dataSource.setMaxIdle(maxSize); dataSource.setMaxIdle(maxSize);
this.initPool(dataSource);
return dataSource; return dataSource;
} }
private void initPool(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
}
} }
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