Implement Vibur DBCP connection pool metrics (#6092)
* Implement Vibur DBCP connection pool metrics * Apply suggestions from code review Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> * address review comments * don't check for metircs that aren't reported * rework library test setup Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
4586db491d
commit
b95b64ba88
|
@ -31,6 +31,7 @@ that can be used if you prefer that over using the Java agent:
|
|||
* [Spring RestTemplate](../instrumentation/spring/spring-web-3.1/library)
|
||||
* [Spring Web MVC](../instrumentation/spring/spring-webmvc-3.1/library)
|
||||
* [Spring WebFlux Client](../instrumentation/spring/spring-webflux-5.0/library)
|
||||
* [Vibur DBCP](../instrumentation/vibur-dbcp-11.0/library)
|
||||
|
||||
And some libraries are publishing their own OpenTelemetry instrumentation (yay!), e.g.
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ These are the supported libraries and frameworks:
|
|||
| [Vert.x HttpClient](https://vertx.io/docs/apidocs/io/vertx/core/http/HttpClient.html) | 3.0+ |
|
||||
| [Vert.x Kafka Client](https://vertx.io/docs/vertx-kafka-client/java/) | 3.6+ |
|
||||
| [Vert.x RxJava2](https://vertx.io/docs/vertx-rx/java2/) | 3.5+ |
|
||||
| [Vibur DBCP](https://www.vibur.org/) | 11.0+ |
|
||||
|
||||
## Application Servers
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
plugins {
|
||||
id("otel.javaagent-instrumentation")
|
||||
}
|
||||
|
||||
muzzle {
|
||||
pass {
|
||||
group.set("org.vibur")
|
||||
module.set("vibur-dbcp")
|
||||
versions.set("[11.0,)")
|
||||
assertInverse.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
library("org.vibur:vibur-dbcp:11.0")
|
||||
|
||||
implementation(project(":instrumentation:vibur-dbcp-11.0:library"))
|
||||
|
||||
testImplementation(project(":instrumentation:vibur-dbcp-11.0:testing"))
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.viburdbcp;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.viburdbcp.ViburSingletons.telemetry;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
final class ViburDbcpDataSourceInstrumentation implements TypeInstrumentation {
|
||||
|
||||
@Override
|
||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||
return named("org.vibur.dbcp.ViburDBCPDataSource");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(TypeTransformer transformer) {
|
||||
transformer.applyAdviceToMethod(
|
||||
named("start").and(takesArguments(0)), this.getClass().getName() + "$StartAdvice");
|
||||
transformer.applyAdviceToMethod(
|
||||
named("close").and(takesArguments(0)), this.getClass().getName() + "$CloseAdvice");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class StartAdvice {
|
||||
|
||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||
public static void onExit(@Advice.This ViburDBCPDataSource dataSource) {
|
||||
telemetry().registerMetrics(dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class CloseAdvice {
|
||||
|
||||
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
|
||||
public static void onExit(@Advice.This ViburDBCPDataSource dataSource) {
|
||||
telemetry().unregisterMetrics(dataSource);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.viburdbcp;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import java.util.List;
|
||||
|
||||
@AutoService(InstrumentationModule.class)
|
||||
public class ViburDbcpInstrumentationModule extends InstrumentationModule {
|
||||
public ViburDbcpInstrumentationModule() {
|
||||
super("vibur-dbcp", "vibur-dbcp-11.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TypeInstrumentation> typeInstrumentations() {
|
||||
return singletonList(new ViburDbcpDataSourceInstrumentation());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.viburdbcp;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.viburdbcp.ViburTelemetry;
|
||||
|
||||
public final class ViburSingletons {
|
||||
|
||||
private static final ViburTelemetry viburTelemetry =
|
||||
ViburTelemetry.create(GlobalOpenTelemetry.get());
|
||||
|
||||
public static ViburTelemetry telemetry() {
|
||||
return viburTelemetry;
|
||||
}
|
||||
|
||||
private ViburSingletons() {}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.viburdbcp;
|
||||
|
||||
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.viburdbcp.AbstractViburInstrumentationTest;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
class ViburInstrumentationTest extends AbstractViburInstrumentationTest {
|
||||
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||
|
||||
@Override
|
||||
protected InstrumentationExtension testing() {
|
||||
return testing;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ViburDBCPDataSource viburDataSource) {}
|
||||
|
||||
@Override
|
||||
protected void shutdown(ViburDBCPDataSource viburDataSource) {}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
# Manual Instrumentation for Vibur DBCP
|
||||
|
||||
Provides OpenTelemetry instrumentation for [Vibur DBCP](https://www.vibur.org/).
|
||||
|
||||
## Quickstart
|
||||
|
||||
### Add these dependencies to your project:
|
||||
|
||||
Replace `OPENTELEMETRY_VERSION` with the latest stable
|
||||
[release](https://mvnrepository.com/artifact/io.opentelemetry). `Minimum version: 1.15.0`
|
||||
|
||||
For Maven, add to your `pom.xml` dependencies:
|
||||
|
||||
```xml
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry.instrumentation</groupId>
|
||||
<artifactId>opentelemetry-viburdbcp-11.0</artifactId>
|
||||
<version>OPENTELEMETRY_VERSION</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
For Gradle, add to your dependencies:
|
||||
|
||||
```groovy
|
||||
implementation("io.opentelemetry.instrumentation:opentelemetry-viburdbcp-11.0:OPENTELEMETRY_VERSION")
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
The instrumentation library allows registering `ViburDBCPDataSource` instances for collecting
|
||||
OpenTelemetry-based metrics.
|
||||
|
||||
```java
|
||||
ViburTelemetry viburTelemetry;
|
||||
|
||||
void configure(OpenTelemetry openTelemetry, ViburDBCPDataSource viburDataSource) {
|
||||
viburTelemetry = ViburTelemetry.create(openTelemetry);
|
||||
viburTelemetry.registerMetrics(viburDataSource);
|
||||
}
|
||||
|
||||
void destroy(ViburDBCPDataSource viburDataSource) {
|
||||
viburTelemetry.unregisterMetrics(viburDataSource);
|
||||
}
|
||||
```
|
|
@ -0,0 +1,10 @@
|
|||
plugins {
|
||||
id("otel.library-instrumentation")
|
||||
id("otel.nullaway-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
library("org.vibur:vibur-dbcp:11.0")
|
||||
|
||||
testImplementation(project(":instrumentation:vibur-dbcp-11.0:testing"))
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.viburdbcp;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.metrics.ObservableLongUpDownCounter;
|
||||
import io.opentelemetry.instrumentation.api.metrics.db.DbConnectionPoolMetrics;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
final class ConnectionPoolMetrics {
|
||||
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.viburdbcp-11.0";
|
||||
|
||||
// a weak map does not make sense here because each Meter holds a reference to the dataSource
|
||||
// ViburDBCPDataSource does not implement equals()/hashCode(), so it's safe to keep them in a
|
||||
// plain ConcurrentHashMap
|
||||
private static final Map<ViburDBCPDataSource, List<ObservableLongUpDownCounter>>
|
||||
dataSourceMetrics = new ConcurrentHashMap<>();
|
||||
|
||||
public static void registerMetrics(OpenTelemetry openTelemetry, ViburDBCPDataSource dataSource) {
|
||||
dataSourceMetrics.computeIfAbsent(
|
||||
dataSource, (unused) -> createMeters(openTelemetry, dataSource));
|
||||
}
|
||||
|
||||
private static List<ObservableLongUpDownCounter> createMeters(
|
||||
OpenTelemetry openTelemetry, ViburDBCPDataSource dataSource) {
|
||||
DbConnectionPoolMetrics metrics =
|
||||
DbConnectionPoolMetrics.create(openTelemetry, INSTRUMENTATION_NAME, dataSource.getName());
|
||||
|
||||
return Arrays.asList(
|
||||
metrics.usedConnections(() -> dataSource.getPool().taken()),
|
||||
metrics.idleConnections(() -> dataSource.getPool().remainingCreated()),
|
||||
metrics.maxConnections(dataSource::getPoolMaxSize));
|
||||
}
|
||||
|
||||
public static void unregisterMetrics(ViburDBCPDataSource dataSource) {
|
||||
List<ObservableLongUpDownCounter> observableInstruments = dataSourceMetrics.remove(dataSource);
|
||||
if (observableInstruments != null) {
|
||||
for (ObservableLongUpDownCounter observable : observableInstruments) {
|
||||
observable.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionPoolMetrics() {}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.viburdbcp;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
/** Entrypoint for instrumenting Vibur database connection pools. */
|
||||
public final class ViburTelemetry {
|
||||
|
||||
/** Returns a new {@link ViburTelemetry} configured with the given {@link OpenTelemetry}. */
|
||||
public static ViburTelemetry create(OpenTelemetry openTelemetry) {
|
||||
return new ViburTelemetry(openTelemetry);
|
||||
}
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
|
||||
private ViburTelemetry(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
}
|
||||
|
||||
/** Start collecting metrics for given data source. */
|
||||
public void registerMetrics(ViburDBCPDataSource dataSource) {
|
||||
ConnectionPoolMetrics.registerMetrics(openTelemetry, dataSource);
|
||||
}
|
||||
|
||||
/** Stop collecting metrics for given data source. */
|
||||
public void unregisterMetrics(ViburDBCPDataSource dataSource) {
|
||||
ConnectionPoolMetrics.unregisterMetrics(dataSource);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.viburdbcp;
|
||||
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
class ViburInstrumentationTest extends AbstractViburInstrumentationTest {
|
||||
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||
|
||||
private static ViburTelemetry telemetry;
|
||||
|
||||
@Override
|
||||
protected InstrumentationExtension testing() {
|
||||
return testing;
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
telemetry = ViburTelemetry.create(testing.getOpenTelemetry());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ViburDBCPDataSource viburDataSource) {
|
||||
telemetry.registerMetrics(viburDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutdown(ViburDBCPDataSource viburDataSource) {
|
||||
telemetry.unregisterMetrics(viburDataSource);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
plugins {
|
||||
id("otel.java-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":testing-common"))
|
||||
api("org.mockito:mockito-core")
|
||||
api("org.mockito:mockito-junit-jupiter")
|
||||
|
||||
compileOnly("org.vibur:vibur-dbcp:11.0")
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.viburdbcp;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.db.DbConnectionPoolMetricsAssertions;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.sql.DataSource;
|
||||
import org.assertj.core.api.AbstractIterableAssert;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public abstract class AbstractViburInstrumentationTest {
|
||||
|
||||
@RegisterExtension static final AutoCleanupExtension cleanup = AutoCleanupExtension.create();
|
||||
|
||||
@Mock DataSource dataSourceMock;
|
||||
@Mock Connection connectionMock;
|
||||
|
||||
protected abstract InstrumentationExtension testing();
|
||||
|
||||
protected abstract void configure(ViburDBCPDataSource viburDataSource);
|
||||
|
||||
protected abstract void shutdown(ViburDBCPDataSource viburDataSource);
|
||||
|
||||
@Test
|
||||
void shouldReportMetrics() throws SQLException, InterruptedException {
|
||||
// given
|
||||
when(dataSourceMock.getConnection()).thenReturn(connectionMock);
|
||||
|
||||
ViburDBCPDataSource viburDataSource = new ViburDBCPDataSource();
|
||||
viburDataSource.setExternalDataSource(dataSourceMock);
|
||||
viburDataSource.setName("testPool");
|
||||
configure(viburDataSource);
|
||||
viburDataSource.start();
|
||||
|
||||
// when
|
||||
Connection viburConnection = viburDataSource.getConnection();
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
viburConnection.close();
|
||||
|
||||
// then
|
||||
DbConnectionPoolMetricsAssertions.create(
|
||||
testing(), "io.opentelemetry.viburdbcp-11.0", "testPool")
|
||||
.disableMinIdleConnections()
|
||||
.disableMaxIdleConnections()
|
||||
.disablePendingRequests()
|
||||
.disableConnectionTimeouts()
|
||||
.disableCreateTime()
|
||||
.disableWaitTime()
|
||||
.disableUseTime()
|
||||
.assertConnectionPoolEmitsMetrics();
|
||||
|
||||
// when
|
||||
// this one too shouldn't cause any problems when called more than once
|
||||
viburDataSource.close();
|
||||
viburDataSource.close();
|
||||
shutdown(viburDataSource);
|
||||
|
||||
// sleep exporter interval
|
||||
Thread.sleep(100);
|
||||
testing().clearData();
|
||||
Thread.sleep(100);
|
||||
|
||||
// then
|
||||
testing()
|
||||
.waitAndAssertMetrics(
|
||||
"io.opentelemetry.viburdbcp-11.0",
|
||||
"db.client.connections.usage",
|
||||
AbstractIterableAssert::isEmpty);
|
||||
testing()
|
||||
.waitAndAssertMetrics(
|
||||
"io.opentelemetry.viburdbcp-11.0",
|
||||
"db.client.connections.max",
|
||||
AbstractIterableAssert::isEmpty);
|
||||
}
|
||||
}
|
|
@ -442,6 +442,9 @@ include(":instrumentation:vertx:vertx-kafka-client-3.6:testing")
|
|||
include(":instrumentation:vertx:vertx-rx-java-3.5:javaagent")
|
||||
include(":instrumentation:vertx:vertx-web-3.0:javaagent")
|
||||
include(":instrumentation:vertx:vertx-web-3.0:testing")
|
||||
include(":instrumentation:vibur-dbcp-11.0:javaagent")
|
||||
include(":instrumentation:vibur-dbcp-11.0:library")
|
||||
include(":instrumentation:vibur-dbcp-11.0:testing")
|
||||
include(":instrumentation:wicket-8.0:javaagent")
|
||||
|
||||
// benchmark
|
||||
|
|
|
@ -22,8 +22,13 @@ public final class DbConnectionPoolMetricsAssertions {
|
|||
private final String instrumentationName;
|
||||
private final String poolName;
|
||||
|
||||
private boolean testMinIdleConnections = true;
|
||||
private boolean testMaxIdleConnections = true;
|
||||
private boolean testPendingRequests = true;
|
||||
private boolean testConnectionTimeouts = true;
|
||||
private boolean testCreateTime = true;
|
||||
private boolean testWaitTime = true;
|
||||
private boolean testUseTime = true;
|
||||
|
||||
DbConnectionPoolMetricsAssertions(
|
||||
InstrumentationExtension testing, String instrumentationName, String poolName) {
|
||||
|
@ -32,16 +37,41 @@ public final class DbConnectionPoolMetricsAssertions {
|
|||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableMinIdleConnections() {
|
||||
testMinIdleConnections = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableMaxIdleConnections() {
|
||||
testMaxIdleConnections = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disablePendingRequests() {
|
||||
testPendingRequests = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableConnectionTimeouts() {
|
||||
testConnectionTimeouts = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableCreateTime() {
|
||||
testCreateTime = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableWaitTime() {
|
||||
testWaitTime = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbConnectionPoolMetricsAssertions disableUseTime() {
|
||||
testUseTime = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void assertConnectionPoolEmitsMetrics() {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
|
@ -71,23 +101,25 @@ public final class DbConnectionPoolMetricsAssertions {
|
|||
poolName,
|
||||
stringKey("state"),
|
||||
"used"))))));
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.idle.min",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("connections")
|
||||
.hasDescription("The minimum number of idle open connections allowed.")
|
||||
.hasLongSumSatisfying(
|
||||
sum ->
|
||||
sum.isNotMonotonic()
|
||||
.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
if (testMinIdleConnections) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.idle.min",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("connections")
|
||||
.hasDescription("The minimum number of idle open connections allowed.")
|
||||
.hasLongSumSatisfying(
|
||||
sum ->
|
||||
sum.isNotMonotonic()
|
||||
.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
if (testMaxIdleConnections) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
|
@ -124,24 +156,26 @@ public final class DbConnectionPoolMetricsAssertions {
|
|||
point.hasAttributes(
|
||||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.pending_requests",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("requests")
|
||||
.hasDescription(
|
||||
"The number of pending requests for an open connection, cumulative for the entire pool.")
|
||||
.hasLongSumSatisfying(
|
||||
sum ->
|
||||
sum.isNotMonotonic()
|
||||
.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
if (testPendingRequests) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.pending_requests",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("requests")
|
||||
.hasDescription(
|
||||
"The number of pending requests for an open connection, cumulative for the entire pool.")
|
||||
.hasLongSumSatisfying(
|
||||
sum ->
|
||||
sum.isNotMonotonic()
|
||||
.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
if (testConnectionTimeouts) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
|
@ -162,52 +196,58 @@ public final class DbConnectionPoolMetricsAssertions {
|
|||
Attributes.of(
|
||||
stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.create_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription("The time it took to create a new connection.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.wait_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription(
|
||||
"The time it took to obtain an open connection from the pool.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.use_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription(
|
||||
"The time between borrowing a connection and returning it to the pool.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
if (testCreateTime) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.create_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription("The time it took to create a new connection.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
if (testWaitTime) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.wait_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription(
|
||||
"The time it took to obtain an open connection from the pool.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
if (testUseTime) {
|
||||
testing.waitAndAssertMetrics(
|
||||
instrumentationName,
|
||||
"db.client.connections.use_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasUnit("ms")
|
||||
.hasDescription(
|
||||
"The time between borrowing a connection and returning it to the pool.")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point.hasAttributes(
|
||||
Attributes.of(stringKey("pool.name"), poolName))))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue