When using the standard HikariCP Micrometer is automatically enabled.
It would be helpful to have that with UCP as well.
public class UcpPoolMetrics implements MeterBinder {
private final PoolDataSource poolDataSource;
private final Tags tags;
public UcpPoolMetrics(PoolDataSource poolDataSource) {
this.poolDataSource = poolDataSource;
var poolName = poolDataSource.getConnectionPoolName();
this.tags = Tags.of("pool", poolName != null ? poolName : "ucp");
}
@Override
public void bindTo(MeterRegistry registry) {
gauge(registry, "ucp.connections", "Total connections in the pool",
UniversalConnectionPoolStatistics::getTotalConnectionsCount);
gauge(registry, "ucp.connections.active", "Borrowed (in use) connections",
UniversalConnectionPoolStatistics::getBorrowedConnectionsCount);
gauge(registry, "ucp.connections.idle", "Available (idle) connections",
UniversalConnectionPoolStatistics::getAvailableConnectionsCount);
gauge(registry, "ucp.connections.pending", "Threads waiting for a connection",
UniversalConnectionPoolStatistics::getPendingRequestsCount);
gauge(registry, "ucp.connections.peak", "Peak connection count since pool start",
UniversalConnectionPoolStatistics::getPeakConnectionsCount);
Gauge.builder("ucp.connections.min", this.poolDataSource, PoolDataSource::getMinPoolSize)
.tags(this.tags)
.description("Configured minimum pool size")
.register(registry);
Gauge.builder("ucp.connections.max", this.poolDataSource, PoolDataSource::getMaxPoolSize)
.tags(this.tags)
.description("Configured maximum pool size")
.register(registry);
// Not named "created": OpenMetrics reserves the _created suffix, so a meter named
// ucp.connections.created would collide with the ucp.connections gauge.
counter(registry, "ucp.connections.opened", "Physical connections created",
UniversalConnectionPoolStatistics::getConnectionsCreatedCount);
counter(registry, "ucp.connections.closed", "Physical connections closed",
UniversalConnectionPoolStatistics::getConnectionsClosedCount);
counter(registry, "ucp.connections.abandoned", "Connections reclaimed as abandoned",
UniversalConnectionPoolStatistics::getAbandonedConnectionsCount);
counter(registry, "ucp.connections.timeout", "Failed connection borrow attempts (wait failures)",
UniversalConnectionPoolStatistics::getCumulativeFailedConnectionWaitCount);
FunctionTimer
.builder("ucp.connections.acquire", this.poolDataSource,
ds -> (long) statistic(ds, UniversalConnectionPoolStatistics::getCumulativeConnectionBorrowedCount),
ds -> statistic(ds, UniversalConnectionPoolStatistics::getCumulativeConnectionWaitTime),
TimeUnit.MILLISECONDS)
.tags(this.tags)
.description("Time spent waiting to borrow a connection")
.register(registry);
FunctionTimer
.builder("ucp.connections.usage", this.poolDataSource,
ds -> (long) statistic(ds, UniversalConnectionPoolStatistics::getCumulativeConnectionReturnedCount),
ds -> statistic(ds, UniversalConnectionPoolStatistics::getCumulativeConnectionUseTime),
TimeUnit.MILLISECONDS)
.tags(this.tags)
.description("Time connections spend borrowed before being returned")
.register(registry);
}
private void gauge(MeterRegistry registry, String name, String description,
ToDoubleFunction<UniversalConnectionPoolStatistics> value) {
Gauge.builder(name, this.poolDataSource, ds -> statistic(ds, value))
.tags(this.tags)
.description(description)
.register(registry);
}
private void counter(MeterRegistry registry, String name, String description,
ToDoubleFunction<UniversalConnectionPoolStatistics> value) {
FunctionCounter.builder(name, this.poolDataSource, ds -> statistic(ds, value))
.tags(this.tags)
.description(description)
.register(registry);
}
/**
* UCP returns no statistics object before the pool has been started.
*/
private static double statistic(PoolDataSource poolDataSource,
ToDoubleFunction<UniversalConnectionPoolStatistics> value) {
var statistics = poolDataSource.getStatistics();
return statistics != null ? value.applyAsDouble(statistics) : 0;
}
}
When using the standard HikariCP Micrometer is automatically enabled.
It would be helpful to have that with UCP as well.
Currently I do this: