Skip to content

Commit

Permalink
Implement HikariCP library instrumentation (open-telemetry#6023)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek authored and RashmiRam committed May 23, 2022
1 parent 3c3c7a1 commit 2b48cc8
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 38 deletions.
1 change: 1 addition & 0 deletions docs/standalone-library-instrumentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ that can be used if you prefer that over using the Java agent:
* [gRPC](../instrumentation/grpc-1.6/library)
* [Guava](../instrumentation/guava-10.0/library)
* [GraphQL Java](../instrumentation/graphql-java-12.0/library)
* [HikariCP](../instrumentation/hikaricp-3.0/library)
* [JDBC](../instrumentation/jdbc/library)
* [Ktor 1.0](../instrumentation/ktor/ktor-1.0/library)
* [Ktor 2.0](../instrumentation/ktor/ktor-2.0/library)
Expand Down
4 changes: 4 additions & 0 deletions instrumentation/hikaricp-3.0/javaagent/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ muzzle {

dependencies {
library("com.zaxxer:HikariCP:3.0.0")

implementation(project(":instrumentation:hikaricp-3.0:library"))

testImplementation(project(":instrumentation:hikaricp-3.0:testing"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,9 @@ public static class SetMetricsTrackerFactoryAdvice {

@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(value = 0, readOnly = false) MetricsTrackerFactory metricsTrackerFactory) {
@Advice.Argument(value = 0, readOnly = false) MetricsTrackerFactory userMetricsTracker) {

if (!(metricsTrackerFactory instanceof OpenTelemetryMetricsTrackerFactory)) {
metricsTrackerFactory = new OpenTelemetryMetricsTrackerFactory(metricsTrackerFactory);
}
userMetricsTracker = HikariSingletons.createMetricsTrackerFactory(userMetricsTracker);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.hikaricp;

import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.hikaricp.HikariTelemetry;
import javax.annotation.Nullable;

public final class HikariSingletons {

private static final HikariTelemetry hikariTelemetry =
HikariTelemetry.create(GlobalOpenTelemetry.get());

public static MetricsTrackerFactory createMetricsTrackerFactory(
@Nullable MetricsTrackerFactory delegate) {
return hikariTelemetry.createMetricsTrackerFactory(delegate);
}

private HikariSingletons() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.hikaricp;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import io.opentelemetry.instrumentation.hikaricp.AbstractHikariInstrumentationTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.RegisterExtension;

class HikariInstrumentationTest extends AbstractHikariInstrumentationTest {

@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
protected void configure(HikariConfig poolConfig, @Nullable MetricsTrackerFactory userTracker) {
if (userTracker != null) {
poolConfig.setMetricsTrackerFactory(userTracker);
}
}
}
41 changes: 41 additions & 0 deletions instrumentation/hikaricp-3.0/library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Manual Instrumentation for HikariCP

Provides OpenTelemetry instrumentation for [HikariCP](https://github.com/brettwooldridge/HikariCP).

## Quickstart

### Add these dependencies to your project:

Replace `OPENTELEMETRY_VERSION` with the latest stable
[release](https://mvnrepository.com/artifact/io.opentelemetry). `Minimum version: 1.14.0`

For Maven, add to your `pom.xml` dependencies:

```xml

<dependencies>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-hikaricp-3.0</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
</dependencies>
```

For Gradle, add to your dependencies:

```groovy
implementation("io.opentelemetry.instrumentation:opentelemetry-hikaricp-3.0:OPENTELEMETRY_VERSION")
```

### Usage

The instrumentation library provides a `MetricsTrackerFactory` implementation that can be added to
an instance of the `HikariConfig` (or `HikariDataSource`) to provide OpenTelemetry-based metrics.

```java
void configure(OpenTelemetry openTelemetry, HikariConfig connectionPoolConfig) {
HikariTelemetry telemetry = HikariTelemetry.create(openTelemetry);
connectionPoolConfig.setMetricsTrackerFactory(telemetry.createMetricsTrackerFactory());
}
```
10 changes: 10 additions & 0 deletions instrumentation/hikaricp-3.0/library/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
plugins {
id("otel.library-instrumentation")
id("otel.nullaway-conventions")
}

dependencies {
library("com.zaxxer:HikariCP:3.0.0")

testImplementation(project(":instrumentation:hikaricp-3.0:testing"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.hikaricp;

import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import io.opentelemetry.api.OpenTelemetry;
import javax.annotation.Nullable;

/** Entrypoint for instrumenting Hikari database connection pools. */
public final class HikariTelemetry {

/** Returns a new {@link HikariTelemetry} configured with the given {@link OpenTelemetry}. */
public static HikariTelemetry create(OpenTelemetry openTelemetry) {
return new HikariTelemetry(openTelemetry);
}

private final OpenTelemetry openTelemetry;

private HikariTelemetry(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry;
}

/**
* Returns a new {@link MetricsTrackerFactory} that can be registered using {@link
* com.zaxxer.hikari.HikariConfig#setMetricsTrackerFactory(MetricsTrackerFactory)}.
*/
public MetricsTrackerFactory createMetricsTrackerFactory() {
return createMetricsTrackerFactory(null);
}

/**
* Returns a new {@link MetricsTrackerFactory} that can be registered using {@link
* com.zaxxer.hikari.HikariConfig#setMetricsTrackerFactory(MetricsTrackerFactory)}. The {@link
* com.zaxxer.hikari.metrics.IMetricsTracker} objects created by the returned factory will
* delegate to trackers created by the {@code delegate} metrics tracker factory, if it is not
* null.
*/
public MetricsTrackerFactory createMetricsTrackerFactory(
@Nullable MetricsTrackerFactory delegate) {
return new OpenTelemetryMetricsTrackerFactory(openTelemetry, delegate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.hikaricp;
package io.opentelemetry.instrumentation.hikaricp;

import com.zaxxer.hikari.metrics.IMetricsTracker;
import io.opentelemetry.api.common.Attributes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,28 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.hikaricp;
package io.opentelemetry.instrumentation.hikaricp;

import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.metrics.PoolStats;
import io.opentelemetry.api.GlobalOpenTelemetry;
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 javax.annotation.Nullable;

public final class OpenTelemetryMetricsTrackerFactory implements MetricsTrackerFactory {
final class OpenTelemetryMetricsTrackerFactory implements MetricsTrackerFactory {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.hikaricp-3.0";

private final OpenTelemetry openTelemetry;
@Nullable private final MetricsTrackerFactory userMetricsFactory;

public OpenTelemetryMetricsTrackerFactory(@Nullable MetricsTrackerFactory userMetricsFactory) {
OpenTelemetryMetricsTrackerFactory(
OpenTelemetry openTelemetry, @Nullable MetricsTrackerFactory userMetricsFactory) {
this.openTelemetry = openTelemetry;
this.userMetricsFactory = userMetricsFactory;
}

Expand All @@ -33,7 +36,7 @@ public IMetricsTracker create(String poolName, PoolStats poolStats) {
: userMetricsFactory.create(poolName, poolStats);

DbConnectionPoolMetrics metrics =
DbConnectionPoolMetrics.create(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, poolName);
DbConnectionPoolMetrics.create(openTelemetry, INSTRUMENTATION_NAME, poolName);

List<ObservableLongUpDownCounter> observableInstruments =
Arrays.asList(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.hikaricp;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.RegisterExtension;

class HikariInstrumentationTest extends AbstractHikariInstrumentationTest {

@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
protected InstrumentationExtension testing() {
return testing;
}

@Override
protected void configure(HikariConfig poolConfig, @Nullable MetricsTrackerFactory userTracker) {
poolConfig.setMetricsTrackerFactory(
HikariTelemetry.create(testing().getOpenTelemetry())
.createMetricsTrackerFactory(userTracker));
}
}
11 changes: 11 additions & 0 deletions instrumentation/hikaricp-3.0/testing/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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("com.zaxxer:HikariCP:3.0.0")
}
Loading

0 comments on commit 2b48cc8

Please sign in to comment.