Skip to content

Instantly share code, notes, and snippets.

@vy
Created June 13, 2019 19:49
Show Gist options
  • Save vy/d9369757dae398423f1eeabf589df543 to your computer and use it in GitHub Desktop.
Save vy/d9369757dae398423f1eeabf589df543 to your computer and use it in GitHub Desktop.
/brettwooldridge/HikariCP/issues/1374
package com.vlkan;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;
public enum HikaricpMicrometerBug {;
public static void main(String[] args) throws SQLException {
// Tickle HikariCP and feed statistics to a MeterRegistry.
PrometheusMeterRegistry meterRegistry1 = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
tickleStatistics(meterRegistry1);
scrapeStatistics(meterRegistry1);
/*
* hitCount: 1825
* hikaricp_connections_acquire_seconds_count{pool="test",} 1.0
* hikaricp_connections_acquire_seconds_sum{pool="test",} 8.0015E-5
* hikaricp_connections_acquire_seconds_max{pool="test",} 8.0015E-5
* hikaricp_connections{pool="test",} 0.0
* hikaricp_connections_usage_seconds_count{pool="test",} 1.0
* hikaricp_connections_usage_seconds_sum{pool="test",} 1.083
* hikaricp_connections_usage_seconds_max{pool="test",} 1.083
* hikaricp_connections_creation_seconds_max{pool="test",} 0.0
* hikaricp_connections_creation_seconds_count{pool="test",} 0.0
* hikaricp_connections_creation_seconds_sum{pool="test",} 0.0
* hikaricp_connections_active{pool="test",} 0.0
* hikaricp_connections_timeout_total{pool="test",} 0.0
* hikaricp_connections_idle{pool="test",} 0.0
* hikaricp_connections_pending{pool="test",} 0.0
* hikaricp_connections_min{pool="test",} 1.0
* hikaricp_connections_max{pool="test",} 1.0
*/
// Tickle HikariCP and feed statistics to a CollectorRegistry.
CollectorRegistry collectorRegistry = new CollectorRegistry();
PrometheusMeterRegistry meterRegistry2 = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT, collectorRegistry, Clock.SYSTEM);
tickleStatistics(collectorRegistry);
scrapeStatistics(meterRegistry2);
/*
* hitCount: 1825
* hikaricp_active_connections{pool="test",} 0.0
* hikaricp_idle_connections{pool="test",} 0.0
* hikaricp_pending_threads{pool="test",} 0.0
* hikaricp_connections{pool="test",} 0.0
* hikaricp_max_connections{pool="test",} 1.0
* hikaricp_min_connections{pool="test",} 1.0
* hikaricp_connection_creation_millis{pool="test",quantile="0.5",} NaN
* hikaricp_connection_creation_millis{pool="test",quantile="0.95",} NaN
* hikaricp_connection_creation_millis{pool="test",quantile="0.99",} NaN
* hikaricp_connection_creation_millis_count{pool="test",} 0.0
* hikaricp_connection_creation_millis_sum{pool="test",} 0.0
* hikaricp_connection_acquired_nanos{pool="test",quantile="0.5",} 17965.0
* hikaricp_connection_acquired_nanos{pool="test",quantile="0.95",} 17965.0
* hikaricp_connection_acquired_nanos{pool="test",quantile="0.99",} 17965.0
* hikaricp_connection_acquired_nanos_count{pool="test",} 1.0
* hikaricp_connection_acquired_nanos_sum{pool="test",} 17965.0
* hikaricp_connection_usage_millis{pool="test",quantile="0.5",} 678.0
* hikaricp_connection_usage_millis{pool="test",quantile="0.95",} 678.0
* hikaricp_connection_usage_millis{pool="test",quantile="0.99",} 678.0
* hikaricp_connection_usage_millis_count{pool="test",} 1.0
* hikaricp_connection_usage_millis_sum{pool="test",} 678.0
* hikaricp_connection_timeout_total{pool="test",} 0.0
*/
}
private static void tickleStatistics(Object meterOrCollectorRegistry) throws SQLException {
try (HikariDataSource dataSource = createHikariDataSource(meterOrCollectorRegistry)) {
try (Connection connection = dataSource.getConnection()) {
// Create table.
try (PreparedStatement statement = connection.prepareStatement("CREATE TABLE number (value INTEGER)")) {
statement.execute();
}
// Populate numbers.
Random random = new Random(0);
int maxNumber = 5_000;
int numberCount = 1_000;
try (PreparedStatement statement = connection.prepareStatement("INSERT INTO number (value) VALUES (?)")) {
for (int numberIndex = 0; numberIndex < numberCount; numberIndex++) {
int number = random.nextInt(maxNumber);
statement.setInt(1, number);
statement.addBatch();
}
statement.executeBatch();
}
// Query numbers.
int queryCount = 10_000;
int hitCount = 0;
for (int queryIndex = 0; queryIndex < queryCount; queryIndex++) {
int number = random.nextInt(maxNumber);
try (PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM number WHERE value = ? LIMIT 1")) {
statement.setInt(1, number);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
hitCount++;
}
}
}
}
System.out.format("hitCount: %d%n", hitCount);
// Commit changes.
connection.commit();
}
}
}
private static HikariDataSource createHikariDataSource(Object meterOrCollectorRegistry) {
HikariConfig hikariConfig = createHikariConfig(meterOrCollectorRegistry);
return new HikariDataSource(hikariConfig);
}
private static HikariConfig createHikariConfig(Object meterOrCollectorRegistry) {
// Create base HikariCP configuration.
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setPoolName("test");
hikariConfig.setDriverClassName("org.h2.Driver");
hikariConfig.setJdbcUrl("jdbc:h2:mem:test");
hikariConfig.setUsername("sa");
hikariConfig.setPassword("");
hikariConfig.setAutoCommit(false);
hikariConfig.setMinimumIdle(1);
hikariConfig.setMaximumPoolSize(1);
hikariConfig.setConnectionTimeout(1_000L);
hikariConfig.setMaxLifetime(30_000L);
hikariConfig.setInitializationFailTimeout(1_000L);
// Set metrics.
if (meterOrCollectorRegistry instanceof MeterRegistry) {
MeterRegistry meterRegistry = (MeterRegistry) meterOrCollectorRegistry;
hikariConfig.setMetricRegistry(meterRegistry);
} else {
CollectorRegistry collectorRegistry = (CollectorRegistry) meterOrCollectorRegistry;
PrometheusMetricsTrackerFactory metricsTrackerFactory = new PrometheusMetricsTrackerFactory(collectorRegistry);
hikariConfig.setMetricsTrackerFactory(metricsTrackerFactory);
}
return hikariConfig;
}
private static void scrapeStatistics(PrometheusMeterRegistry meterRegistry) {
meterRegistry
.scrape()
.lines()
.filter(line -> !line.startsWith("#"))
.forEach(System.out::println);
System.out.println();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vlkan</groupId>
<artifactId>hikaricp-micrometer-bug</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>12</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment