From 634755c862acf19bb6aeff8aba8c27e2b1f66802 Mon Sep 17 00:00:00 2001 From: Simone Giusso Date: Sun, 21 Aug 2022 20:57:30 +0200 Subject: [PATCH 1/3] new cassandra 4.14 module to support reactive tracing --- .../cassandra-4.0/javaagent/build.gradle.kts | 2 + .../v4_0/CompletionStageFunction.java | 1 + .../cassandra-4.0/library/build.gradle.kts | 25 ++++ .../v4_0/CassandraAttributesExtractor.java | 2 +- .../v4_0/CassandraNetAttributesGetter.java | 2 +- .../cassandra/v4_0/CassandraRequest.java | 2 +- .../cassandra/v4_0/CassandraSingletons.java | 2 +- .../v4_0/CassandraSqlAttributesGetter.java | 2 +- .../cassandra/v4_0/TracingCqlSession.java | 4 +- .../cassandra-4.14/javaagent/build.gradle.kts | 29 ++++ .../CassandraClientInstrumentationModule.java | 25 ++++ .../v4_14/CompletionStageFunction.java | 24 ++++ .../v4_14/SessionBuilderInstrumentation.java | 53 +++++++ .../cassandra/v4_14/TracingCqlSession.java | 24 ++++ .../test/groovy/CassandraClientTest.groovy | 129 ++++++++++++++++++ settings.gradle.kts | 2 + 16 files changed, 321 insertions(+), 7 deletions(-) create mode 100644 instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java (97%) rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java (95%) rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/CassandraRequest.java (87%) rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/CassandraSingletons.java (96%) rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java (93%) rename instrumentation/cassandra/cassandra-4.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/cassandra/v4_0/TracingCqlSession.java (97%) create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/build.gradle.kts create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraClientInstrumentationModule.java create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/SessionBuilderInstrumentation.java create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/test/groovy/CassandraClientTest.groovy diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/build.gradle.kts b/instrumentation/cassandra/cassandra-4.0/javaagent/build.gradle.kts index aad53b864a45..97bc74ec5a33 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/build.gradle.kts +++ b/instrumentation/cassandra/cassandra-4.0/javaagent/build.gradle.kts @@ -12,6 +12,8 @@ muzzle { } dependencies { + implementation(project(":instrumentation:cassandra:cassandra-4.0:library")) + library("com.datastax.oss:java-driver-core:4.0.0") compileOnly("com.google.auto.value:auto-value-annotations") diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java index 14aa73c84911..36bd7943fb4e 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java +++ b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.CqlSession; +import io.opentelemetry.instrumentation.cassandra.v4_0.TracingCqlSession; import java.util.function.Function; public class CompletionStageFunction implements Function { diff --git a/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts b/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts new file mode 100644 index 000000000000..aad53b864a45 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +muzzle { + pass { + group.set("com.datastax.oss") + module.set("java-driver-core") + versions.set("[4.0,)") + assertInverse.set(true) + } +} + +dependencies { + library("com.datastax.oss:java-driver-core:4.0.0") + + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") +} + +tasks { + test { + usesService(gradle.sharedServices.registrations["testcontainersBuildService"].getService()) + } +} diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java similarity index 97% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java index be41c016b491..6d025304222e 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java similarity index 95% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java index cb58a2a6d434..6f785e797bee 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.cql.ExecutionInfo; import com.datastax.oss.driver.api.core.metadata.Node; diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraRequest.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraRequest.java similarity index 87% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraRequest.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraRequest.java index 9c783cc3f196..134f060b94b5 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraRequest.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraRequest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.session.Session; import com.google.auto.value.AutoValue; diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java similarity index 96% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java index b84df6935485..c061bc072dcf 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.cql.ExecutionInfo; import io.opentelemetry.api.GlobalOpenTelemetry; diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java similarity index 93% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java index 686966166f3c..d0731c2ffc31 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; import com.datastax.oss.driver.api.core.CqlIdentifier; import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesGetter; diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/TracingCqlSession.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java similarity index 97% rename from instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/TracingCqlSession.java rename to instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java index 726ea9e4db89..4629487bff0d 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/TracingCqlSession.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +package io.opentelemetry.instrumentation.cassandra.v4_0; -import static io.opentelemetry.javaagent.instrumentation.cassandra.v4_0.CassandraSingletons.instrumenter; +import static io.opentelemetry.instrumentation.cassandra.v4_0.CassandraSingletons.instrumenter; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/build.gradle.kts b/instrumentation/cassandra/cassandra-4.14/javaagent/build.gradle.kts new file mode 100644 index 000000000000..b13321a2be7c --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/build.gradle.kts @@ -0,0 +1,29 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +muzzle { + pass { + group.set("com.datastax.oss") + module.set("java-driver-core") + versions.set("[4.14,)") + assertInverse.set(true) + } +} + +dependencies { + implementation(project(":instrumentation:cassandra:cassandra-4.0:library")) + + library("com.datastax.oss:java-driver-core:4.14.1") + + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + + testImplementation("io.projectreactor:reactor-core:3.4.21") +} + +tasks { + test { + usesService(gradle.sharedServices.registrations["testcontainersBuildService"].getService()) + } +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraClientInstrumentationModule.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraClientInstrumentationModule.java new file mode 100644 index 000000000000..eaee3e0acaa0 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraClientInstrumentationModule.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; + +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 CassandraClientInstrumentationModule extends InstrumentationModule { + public CassandraClientInstrumentationModule() { + super("cassandra", "cassandra-4.14"); + } + + @Override + public List typeInstrumentations() { + return singletonList(new SessionBuilderInstrumentation()); + } +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java new file mode 100644 index 000000000000..8c1e070c5c96 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; + +import com.datastax.oss.driver.api.core.CqlSession; +import java.util.function.Function; + +public class CompletionStageFunction implements Function { + + @Override + public Object apply(Object session) { + if (session == null) { + return null; + } + // This should cover ours and OT's TracingCqlSession + if (session.getClass().getName().endsWith("cassandra4.TracingCqlSession")) { + return session; + } + return new TracingCqlSession((CqlSession) session); + } +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/SessionBuilderInstrumentation.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/SessionBuilderInstrumentation.java new file mode 100644 index 000000000000..88a1094d1896 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/SessionBuilderInstrumentation.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; + +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +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 java.util.concurrent.CompletionStage; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class SessionBuilderInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + // Note: Cassandra has a large driver and we instrument single class in it. + // The rest is ignored in AdditionalLibraryIgnoresMatcher + return named("com.datastax.oss.driver.api.core.session.SessionBuilder"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isMethod().and(isPublic()).and(named("buildAsync")).and(takesArguments(0)), + SessionBuilderInstrumentation.class.getName() + "$BuildAdvice"); + } + + @SuppressWarnings("unused") + public static class BuildAdvice { + + /** + * Strategy: each time we build a connection to a Cassandra cluster, the + * com.datastax.oss.driver.api.core.session.SessionBuilder.buildAsync() method is called. The + * opentracing contribution is a simple wrapper, so we just have to wrap the new session. + * + * @param stage The fresh CompletionStage to patch. This stage produces session which is + * replaced with new session + */ + @Advice.OnMethodExit(suppress = Throwable.class) + public static void injectTracingSession( + @Advice.Return(readOnly = false) CompletionStage stage) { + stage = stage.thenApply(new CompletionStageFunction()); + } + } +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java new file mode 100644 index 000000000000..c31e0dc83550 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; + +import com.datastax.dse.driver.api.core.cql.reactive.ReactiveResultSet; +import com.datastax.dse.driver.internal.core.cql.reactive.DefaultReactiveResultSet; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.cql.Statement; + +public class TracingCqlSession + extends io.opentelemetry.instrumentation.cassandra.v4_0.TracingCqlSession { + + public TracingCqlSession(CqlSession session) { + super(session); + } + + @Override + public ReactiveResultSet executeReactive(Statement statement) { + return new DefaultReactiveResultSet(() -> executeAsync(statement)); + } +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/test/groovy/CassandraClientTest.groovy b/instrumentation/cassandra/cassandra-4.14/javaagent/src/test/groovy/CassandraClientTest.groovy new file mode 100644 index 000000000000..e29d3239545e --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/test/groovy/CassandraClientTest.groovy @@ -0,0 +1,129 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import com.datastax.oss.driver.api.core.CqlSession +import com.datastax.oss.driver.api.core.config.DefaultDriverOption +import com.datastax.oss.driver.api.core.config.DriverConfigLoader +import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader +import io.opentelemetry.api.trace.SpanKind +import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification +import io.opentelemetry.instrumentation.test.asserts.TraceAssert +import io.opentelemetry.sdk.trace.data.SpanData +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import reactor.core.publisher.Flux +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.testcontainers.containers.GenericContainer +import org.testcontainers.containers.output.Slf4jLogConsumer +import spock.lang.Shared + +import java.time.Duration + +import static io.opentelemetry.api.trace.SpanKind.CLIENT + +class CassandraClientTest extends AgentInstrumentationSpecification { + private static final Logger logger = LoggerFactory.getLogger(CassandraClientTest) + + @Shared + GenericContainer cassandra + @Shared + int cassandraPort + + def setupSpec() { + cassandra = new GenericContainer("cassandra:4.0") + // limit memory usage + .withEnv("JVM_OPTS", "-Xmx128m -Xms128m") + .withExposedPorts(9042) + .withLogConsumer(new Slf4jLogConsumer(logger)) + .withStartupTimeout(Duration.ofSeconds(120)) + cassandra.start() + + cassandraPort = cassandra.getMappedPort(9042) + } + + def cleanupSpec() { + cassandra.stop() + } + + def "test reactive"() { + setup: + CqlSession session = getSession(keyspace) + + runWithSpan("parent") { + Flux.from(session.executeReactive(statement)).doOnComplete({ result -> + runWithSpan("child") {} + }).blockLast() + } + + expect: + assertTraces(1) { + trace(0, 3) { + span(0) { + name "parent" + kind SpanKind.INTERNAL + hasNoParent() + } + cassandraSpan(it, 1, spanName, expectedStatement, operation, keyspace, table, span(0)) + span(2) { + name "child" + kind SpanKind.INTERNAL + childOf span(0) + } + } + } + + cleanup: + session.close() + + where: + keyspace | statement | expectedStatement | spanName | operation | table + null | "DROP KEYSPACE IF EXISTS reactive_test" | "DROP KEYSPACE IF EXISTS reactive_test" | "DB Query" | null | null + null | "CREATE KEYSPACE reactive_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}" | "CREATE KEYSPACE reactive_test WITH REPLICATION = {?:?, ?:?}" | "DB Query" | null | null + "reactive_test" | "CREATE TABLE reactive_test.users ( id UUID PRIMARY KEY, name text )" | "CREATE TABLE reactive_test.users ( id UUID PRIMARY KEY, name text )" | "reactive_test" | null | null + "reactive_test" | "INSERT INTO reactive_test.users (id, name) values (uuid(), 'alice')" | "INSERT INTO reactive_test.users (id, name) values (uuid(), ?)" | "INSERT reactive_test.users" | "INSERT" | "reactive_test.users" + "reactive_test" | "SELECT * FROM users where name = 'alice' ALLOW FILTERING" | "SELECT * FROM users where name = ? ALLOW FILTERING" | "SELECT reactive_test.users" | "SELECT" | "users" + } + + def cassandraSpan(TraceAssert trace, int index, String spanName, String statement, String operation, String keyspace, String table, Object parentSpan = null) { + trace.span(index) { + name spanName + kind CLIENT + if (parentSpan == null) { + hasNoParent() + } else { + childOf((SpanData) parentSpan) + } + attributes { + "$SemanticAttributes.NET_PEER_NAME" "localhost" + "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" + "$SemanticAttributes.NET_PEER_PORT" cassandraPort + "$SemanticAttributes.DB_SYSTEM" "cassandra" + "$SemanticAttributes.DB_NAME" keyspace + "$SemanticAttributes.DB_STATEMENT" statement + "$SemanticAttributes.DB_OPERATION" operation + "$SemanticAttributes.DB_CASSANDRA_CONSISTENCY_LEVEL" "LOCAL_ONE" + "$SemanticAttributes.DB_CASSANDRA_COORDINATOR_DC" "datacenter1" + "$SemanticAttributes.DB_CASSANDRA_COORDINATOR_ID" String + "$SemanticAttributes.DB_CASSANDRA_IDEMPOTENCE" Boolean + "$SemanticAttributes.DB_CASSANDRA_PAGE_SIZE" 5000 + "$SemanticAttributes.DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT" 0 + // the SqlStatementSanitizer can't handle CREATE statements yet + "$SemanticAttributes.DB_CASSANDRA_TABLE" table + } + } + } + + def getSession(String keyspace) { + DriverConfigLoader configLoader = DefaultDriverConfigLoader.builder() + .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(0)) + .build() + return CqlSession.builder() + .addContactPoint(new InetSocketAddress("localhost", cassandraPort)) + .withConfigLoader(configLoader) + .withLocalDatacenter("datacenter1") + .withKeyspace((String) keyspace) + .build() + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 7fccb475d49e..e70cd14812ca 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -177,6 +177,8 @@ include(":instrumentation:azure-core:azure-core-1.19:javaagent") include(":instrumentation:azure-core:azure-core-1.19:library-instrumentation-shaded") include(":instrumentation:cassandra:cassandra-3.0:javaagent") include(":instrumentation:cassandra:cassandra-4.0:javaagent") +include(":instrumentation:cassandra:cassandra-4.0:library") +include(":instrumentation:cassandra:cassandra-4.14:javaagent") include(":instrumentation:cdi-testing") include(":instrumentation:graphql-java-12.0:javaagent") include(":instrumentation:graphql-java-12.0:library") From f59e4d7b3e381c9daf8ac2320ec55a604b7d6b9a Mon Sep 17 00:00:00 2001 From: Simone Giusso Date: Sun, 21 Aug 2022 22:56:49 +0200 Subject: [PATCH 2/3] fix DuplicateFileCopyingException --- .../cassandra/cassandra-4.0/library/build.gradle.kts | 11 +---------- .../cassandra/v4_0/CassandraSingletons.java | 3 --- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts b/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts index aad53b864a45..0910f423100e 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts +++ b/instrumentation/cassandra/cassandra-4.0/library/build.gradle.kts @@ -1,14 +1,5 @@ plugins { - id("otel.javaagent-instrumentation") -} - -muzzle { - pass { - group.set("com.datastax.oss") - module.set("java-driver-core") - versions.set("[4.0,)") - assertInverse.set(true) - } + id("otel.library-instrumentation") } dependencies { diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java index c061bc072dcf..21d406c9bec2 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java @@ -12,7 +12,6 @@ import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; -import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; public final class CassandraSingletons { @@ -32,8 +31,6 @@ public final class CassandraSingletons { .addAttributesExtractor( SqlClientAttributesExtractor.builder(attributesGetter) .setTableAttribute(SemanticAttributes.DB_CASSANDRA_TABLE) - .setStatementSanitizationEnabled( - CommonConfig.get().isStatementSanitizationEnabled()) .build()) .addAttributesExtractor( NetClientAttributesExtractor.create(new CassandraNetAttributesGetter())) From 128f0f620b863a774d02ded395bd8067ff2e6030 Mon Sep 17 00:00:00 2001 From: Simone Giusso Date: Sat, 27 Aug 2022 18:12:58 +0200 Subject: [PATCH 3/3] Move CassandraSingletons in instrumentation libraries and add new CassandraTelemetry & CassandraTelemetryBuilder files --- .../cassandra/v4_0/CassandraSingletons.java | 34 ++++++++++++ .../v4_0/CompletionStageFunction.java | 4 +- .../v4_0/CassandraAttributesExtractor.java | 2 +- .../v4_0/CassandraNetAttributesGetter.java | 2 +- .../cassandra/v4_0/CassandraSingletons.java | 46 ---------------- .../v4_0/CassandraSqlAttributesGetter.java | 3 +- .../cassandra/v4_0/CassandraTelemetry.java | 53 +++++++++++++++++++ .../v4_0/CassandraTelemetryBuilder.java | 36 +++++++++++++ .../cassandra/v4_0/TracingCqlSession.java | 32 ++++++----- .../cassandra/v4_14/CassandraSingletons.java | 34 ++++++++++++ .../v4_14/CompletionStageFunction.java | 4 +- .../cassandra/v4_14/TracingCqlSession.java | 8 ++- 12 files changed, 188 insertions(+), 70 deletions(-) create mode 100644 instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java delete mode 100644 instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java create mode 100644 instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetry.java create mode 100644 instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetryBuilder.java create mode 100644 instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraSingletons.java diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java new file mode 100644 index 000000000000..202667084e7a --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraSingletons.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; + +import com.datastax.oss.driver.api.core.cql.ExecutionInfo; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.cassandra.v4_0.CassandraRequest; +import io.opentelemetry.instrumentation.cassandra.v4_0.CassandraTelemetry; +import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig; + +public final class CassandraSingletons { + // using ExecutionInfo because we can get that from ResultSet, AsyncResultSet and DriverException + private static final Instrumenter INSTRUMENTER; + + static { + CassandraTelemetry telemetry = + CassandraTelemetry.builder(GlobalOpenTelemetry.get()) + .setInstrumentationName("io.opentelemetry.cassandra-4.0") + .setStatementSanitizationEnabled(CommonConfig.get().isStatementSanitizationEnabled()) + .build(); + + INSTRUMENTER = telemetry.getInstrumenter(); + } + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private CassandraSingletons() {} +} diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java index 36bd7943fb4e..7f8c2ec5b77a 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java +++ b/instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CompletionStageFunction.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +import static io.opentelemetry.javaagent.instrumentation.cassandra.v4_0.CassandraSingletons.instrumenter; + import com.datastax.oss.driver.api.core.CqlSession; import io.opentelemetry.instrumentation.cassandra.v4_0.TracingCqlSession; import java.util.function.Function; @@ -20,6 +22,6 @@ public Object apply(Object session) { if (session.getClass().getName().endsWith("cassandra4.TracingCqlSession")) { return session; } - return new TracingCqlSession((CqlSession) session); + return new TracingCqlSession((CqlSession) session, instrumenter()); } } diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java index 6d025304222e..75fd0ccc105e 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java @@ -16,7 +16,7 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import javax.annotation.Nullable; -final class CassandraAttributesExtractor +public final class CassandraAttributesExtractor implements AttributesExtractor { @Override diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java index 6f785e797bee..2e8d1fe1b26c 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraNetAttributesGetter.java @@ -12,7 +12,7 @@ import java.net.SocketAddress; import javax.annotation.Nullable; -final class CassandraNetAttributesGetter +public final class CassandraNetAttributesGetter extends InetSocketAddressNetClientAttributesGetter { @Override diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java deleted file mode 100644 index 21d406c9bec2..000000000000 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSingletons.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.cassandra.v4_0; - -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; - -public final class CassandraSingletons { - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.cassandra-4.0"; - - // using ExecutionInfo because we can get that from ResultSet, AsyncResultSet and DriverException - private static final Instrumenter INSTRUMENTER; - - static { - CassandraSqlAttributesGetter attributesGetter = new CassandraSqlAttributesGetter(); - - INSTRUMENTER = - Instrumenter.builder( - GlobalOpenTelemetry.get(), - INSTRUMENTATION_NAME, - DbClientSpanNameExtractor.create(attributesGetter)) - .addAttributesExtractor( - SqlClientAttributesExtractor.builder(attributesGetter) - .setTableAttribute(SemanticAttributes.DB_CASSANDRA_TABLE) - .build()) - .addAttributesExtractor( - NetClientAttributesExtractor.create(new CassandraNetAttributesGetter())) - .addAttributesExtractor(new CassandraAttributesExtractor()) - .buildInstrumenter(SpanKindExtractor.alwaysClient()); - } - - public static Instrumenter instrumenter() { - return INSTRUMENTER; - } - - private CassandraSingletons() {} -} diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java index d0731c2ffc31..4e3c874bbb10 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraSqlAttributesGetter.java @@ -10,7 +10,8 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import javax.annotation.Nullable; -final class CassandraSqlAttributesGetter implements SqlClientAttributesGetter { +public final class CassandraSqlAttributesGetter + implements SqlClientAttributesGetter { @Override public String system(CassandraRequest request) { diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetry.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetry.java new file mode 100644 index 000000000000..41516acea661 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetry.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.cassandra.v4_0; + +import com.datastax.oss.driver.api.core.cql.ExecutionInfo; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; + +public final class CassandraTelemetry { + + public static CassandraTelemetryBuilder builder(OpenTelemetry openTelemetry) { + return new CassandraTelemetryBuilder(openTelemetry); + } + + private final Instrumenter instrumenter; + + CassandraTelemetry( + OpenTelemetry openTelemetry, + String instrumentationName, + boolean statementSanitizationEnabled) { + this.instrumenter = + createInstrumenter(openTelemetry, instrumentationName, statementSanitizationEnabled); + } + + private static Instrumenter createInstrumenter( + OpenTelemetry openTelemetry, String instrumenterName, boolean statementSanitizationEnabled) { + CassandraSqlAttributesGetter attributesGetter = new CassandraSqlAttributesGetter(); + + return Instrumenter.builder( + openTelemetry, instrumenterName, DbClientSpanNameExtractor.create(attributesGetter)) + .addAttributesExtractor( + SqlClientAttributesExtractor.builder(attributesGetter) + .setTableAttribute(SemanticAttributes.DB_CASSANDRA_TABLE) + .setStatementSanitizationEnabled(statementSanitizationEnabled) + .build()) + .addAttributesExtractor( + NetClientAttributesExtractor.create(new CassandraNetAttributesGetter())) + .addAttributesExtractor(new CassandraAttributesExtractor()) + .buildInstrumenter(SpanKindExtractor.alwaysClient()); + } + + public Instrumenter getInstrumenter() { + return instrumenter; + } +} diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetryBuilder.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetryBuilder.java new file mode 100644 index 000000000000..986cb0de1b43 --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/CassandraTelemetryBuilder.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.cassandra.v4_0; + +import io.opentelemetry.api.OpenTelemetry; + +public class CassandraTelemetryBuilder { + + static final String DEFAULT_INSTRUMENTATION_NAME = "io.opentelemetry.cassandra"; + + private final OpenTelemetry openTelemetry; + + private String instrumentationName = DEFAULT_INSTRUMENTATION_NAME; + private boolean statementSanitizationEnabled; + + public CassandraTelemetryBuilder(OpenTelemetry openTelemetry) { + this.openTelemetry = openTelemetry; + } + + public CassandraTelemetryBuilder setInstrumentationName(String instrumentationName) { + this.instrumentationName = instrumentationName; + return this; + } + + public CassandraTelemetryBuilder setStatementSanitizationEnabled(boolean enabled) { + this.statementSanitizationEnabled = enabled; + return this; + } + + public CassandraTelemetry build() { + return new CassandraTelemetry(openTelemetry, instrumentationName, statementSanitizationEnabled); + } +} diff --git a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java index 4629487bff0d..5e592a12c15f 100644 --- a/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java +++ b/instrumentation/cassandra/cassandra-4.0/library/src/main/java/io/opentelemetry/instrumentation/cassandra/v4_0/TracingCqlSession.java @@ -5,8 +5,6 @@ package io.opentelemetry.instrumentation.cassandra.v4_0; -import static io.opentelemetry.instrumentation.cassandra.v4_0.CassandraSingletons.instrumenter; - import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.DriverException; @@ -25,6 +23,7 @@ import com.datastax.oss.driver.api.core.type.reflect.GenericType; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -33,9 +32,12 @@ public class TracingCqlSession implements CqlSession { private final CqlSession session; + private final Instrumenter instrumenter; - public TracingCqlSession(CqlSession session) { + public TracingCqlSession( + CqlSession session, Instrumenter instrumenter) { this.session = session; + this.instrumenter = instrumenter; } @Override @@ -158,15 +160,15 @@ public RESULT execute( @Override public ResultSet execute(String query) { CassandraRequest request = CassandraRequest.create(session, query); - Context context = instrumenter().start(Context.current(), request); + Context context = instrumenter.start(Context.current(), request); ResultSet resultSet; try (Scope ignored = context.makeCurrent()) { resultSet = session.execute(query); } catch (RuntimeException e) { - instrumenter().end(context, request, getExecutionInfo(e), e); + instrumenter.end(context, request, getExecutionInfo(e), e); throw e; } - instrumenter().end(context, request, resultSet.getExecutionInfo(), null); + instrumenter.end(context, request, resultSet.getExecutionInfo(), null); return resultSet; } @@ -174,15 +176,15 @@ public ResultSet execute(String query) { public ResultSet execute(Statement statement) { String query = getQuery(statement); CassandraRequest request = CassandraRequest.create(session, query); - Context context = instrumenter().start(Context.current(), request); + Context context = instrumenter.start(Context.current(), request); ResultSet resultSet; try (Scope ignored = context.makeCurrent()) { resultSet = session.execute(statement); } catch (RuntimeException e) { - instrumenter().end(context, request, getExecutionInfo(e), e); + instrumenter.end(context, request, getExecutionInfo(e), e); throw e; } - instrumenter().end(context, request, resultSet.getExecutionInfo(), null); + instrumenter.end(context, request, resultSet.getExecutionInfo(), null); return resultSet; } @@ -199,21 +201,17 @@ public CompletionStage executeAsync(String query) { return executeAsync(request, () -> session.executeAsync(query)); } - private static CompletionStage executeAsync( + private CompletionStage executeAsync( CassandraRequest request, Supplier> query) { Context parentContext = Context.current(); - Context context = instrumenter().start(parentContext, request); + Context context = instrumenter.start(parentContext, request); try (Scope ignored = context.makeCurrent()) { CompletionStage stage = query.get(); return wrap( stage.whenComplete( (asyncResultSet, throwable) -> - instrumenter() - .end( - context, - request, - getExecutionInfo(asyncResultSet, throwable), - throwable)), + instrumenter.end( + context, request, getExecutionInfo(asyncResultSet, throwable), throwable)), parentContext); } } diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraSingletons.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraSingletons.java new file mode 100644 index 000000000000..3ff49266416b --- /dev/null +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CassandraSingletons.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; + +import com.datastax.oss.driver.api.core.cql.ExecutionInfo; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.cassandra.v4_0.CassandraRequest; +import io.opentelemetry.instrumentation.cassandra.v4_0.CassandraTelemetry; +import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig; + +public final class CassandraSingletons { + // using ExecutionInfo because we can get that from ResultSet, AsyncResultSet and DriverException + private static final Instrumenter INSTRUMENTER; + + static { + CassandraTelemetry telemetry = + CassandraTelemetry.builder(GlobalOpenTelemetry.get()) + .setInstrumentationName("io.opentelemetry.cassandra-4.14") + .setStatementSanitizationEnabled(CommonConfig.get().isStatementSanitizationEnabled()) + .build(); + + INSTRUMENTER = telemetry.getInstrumenter(); + } + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private CassandraSingletons() {} +} diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java index 8c1e070c5c96..2d2f5cae6403 100644 --- a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/CompletionStageFunction.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.cassandra.v4_14; +import static io.opentelemetry.javaagent.instrumentation.cassandra.v4_14.CassandraSingletons.instrumenter; + import com.datastax.oss.driver.api.core.CqlSession; import java.util.function.Function; @@ -19,6 +21,6 @@ public Object apply(Object session) { if (session.getClass().getName().endsWith("cassandra4.TracingCqlSession")) { return session; } - return new TracingCqlSession((CqlSession) session); + return new TracingCqlSession((CqlSession) session, instrumenter()); } } diff --git a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java index c31e0dc83550..3a8c0f44a93c 100644 --- a/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java +++ b/instrumentation/cassandra/cassandra-4.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_14/TracingCqlSession.java @@ -8,13 +8,17 @@ import com.datastax.dse.driver.api.core.cql.reactive.ReactiveResultSet; import com.datastax.dse.driver.internal.core.cql.reactive.DefaultReactiveResultSet; import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.cql.ExecutionInfo; import com.datastax.oss.driver.api.core.cql.Statement; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.cassandra.v4_0.CassandraRequest; public class TracingCqlSession extends io.opentelemetry.instrumentation.cassandra.v4_0.TracingCqlSession { - public TracingCqlSession(CqlSession session) { - super(session); + public TracingCqlSession( + CqlSession session, Instrumenter instrumenter) { + super(session, instrumenter); } @Override