diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonSingletons.java b/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonSingletons.java deleted file mode 100644 index 93b91a0f2fe9..000000000000 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonSingletons.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.redisson; - -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.DbClientAttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; - -public final class RedissonSingletons { - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.redisson-3.0"; - - private static final Instrumenter INSTRUMENTER; - - static { - RedissonDbAttributesGetter dbAttributesGetter = new RedissonDbAttributesGetter(); - RedissonNetAttributesGetter netAttributesGetter = new RedissonNetAttributesGetter(); - - INSTRUMENTER = - Instrumenter.builder( - GlobalOpenTelemetry.get(), - INSTRUMENTATION_NAME, - DbClientSpanNameExtractor.create(dbAttributesGetter)) - .addAttributesExtractor(DbClientAttributesExtractor.create(dbAttributesGetter)) - .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) - .newInstrumenter(SpanKindExtractor.alwaysClient()); - } - - public static Instrumenter instrumenter() { - return INSTRUMENTER; - } - - private RedissonSingletons() {} -} diff --git a/instrumentation/redisson-3.0/javaagent/build.gradle.kts b/instrumentation/redisson/redisson-3.0/javaagent/build.gradle.kts similarity index 59% rename from instrumentation/redisson-3.0/javaagent/build.gradle.kts rename to instrumentation/redisson/redisson-3.0/javaagent/build.gradle.kts index de95aead6560..6ef7cc2b65cc 100644 --- a/instrumentation/redisson-3.0/javaagent/build.gradle.kts +++ b/instrumentation/redisson/redisson-3.0/javaagent/build.gradle.kts @@ -6,18 +6,23 @@ muzzle { pass { group.set("org.redisson") module.set("redisson") - versions.set("[3.0.0,3.17.2)") + versions.set("[3.0.0,3.17.0)") } } dependencies { library("org.redisson:redisson:3.0.0") - // TODO (trask) split out instrumentation into two modules and support 3.17.2+ - latestDepTestLibrary("org.redisson:redisson:3.17.1") + implementation(project(":instrumentation:redisson:redisson-common:javaagent")) compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + + testInstrumentation(project(":instrumentation:redisson:redisson-3.17:javaagent")) + + testImplementation(project(":instrumentation:redisson:redisson-common:testing")) + + latestDepTestLibrary("org.redisson:redisson:3.16.+") } tasks.test { diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisCommandDataInstrumentation.java b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisCommandDataInstrumentation.java similarity index 93% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisCommandDataInstrumentation.java rename to instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisCommandDataInstrumentation.java index 6a7b3237b991..40d0f0ee3ddd 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisCommandDataInstrumentation.java +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisCommandDataInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.redisson; +package io.opentelemetry.javaagent.instrumentation.redisson.v3_0; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.redisson.CompletableFutureWrapper; import java.util.concurrent.CompletableFuture; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisConnectionInstrumentation.java b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisConnectionInstrumentation.java similarity index 88% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisConnectionInstrumentation.java rename to instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisConnectionInstrumentation.java index 589a52f69af5..b414cf17a871 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisConnectionInstrumentation.java +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedisConnectionInstrumentation.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.redisson; +package io.opentelemetry.javaagent.instrumentation.redisson.v3_0; import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; -import static io.opentelemetry.javaagent.instrumentation.redisson.RedissonSingletons.instrumenter; +import static io.opentelemetry.javaagent.instrumentation.redisson.v3_0.RedissonSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -14,6 +14,9 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.redisson.EndOperationListener; +import io.opentelemetry.javaagent.instrumentation.redisson.PromiseWrapper; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonRequest; import java.net.InetSocketAddress; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -57,7 +60,7 @@ public static void onEnter( context = instrumenter().start(parentContext, request); scope = context.makeCurrent(); - promise.setEndOperationListener(new EndOperationListener<>(context, request)); + promise.setEndOperationListener(new EndOperationListener<>(instrumenter(), context, request)); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumentationModule.java b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonInstrumentationModule.java similarity index 64% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumentationModule.java rename to instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonInstrumentationModule.java index 7fdff3f7ef6b..8bafa8244d32 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumentationModule.java +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonInstrumentationModule.java @@ -3,14 +3,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.redisson; +package io.opentelemetry.javaagent.instrumentation.redisson.v3_0; +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static java.util.Arrays.asList; +import static net.bytebuddy.matcher.ElementMatchers.not; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) public class RedissonInstrumentationModule extends InstrumentationModule { @@ -19,6 +22,11 @@ public RedissonInstrumentationModule() { super("redisson", "redisson-3.0"); } + @Override + public ElementMatcher.Junction classLoaderMatcher() { + return not(hasClassesNamed("org.redisson.api.RFunction")); + } + @Override public List typeInstrumentations() { return asList(new RedisConnectionInstrumentation(), new RedisCommandDataInstrumentation()); diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonPromiseWrapper.java b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonPromiseWrapper.java similarity index 87% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonPromiseWrapper.java rename to instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonPromiseWrapper.java index 51d5888b533c..efe526cae41e 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonPromiseWrapper.java +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonPromiseWrapper.java @@ -3,10 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.redisson; +package io.opentelemetry.javaagent.instrumentation.redisson.v3_0; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.redisson.EndOperationListener; +import io.opentelemetry.javaagent.instrumentation.redisson.PromiseWrapper; import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; diff --git a/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonSingletons.java b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonSingletons.java new file mode 100644 index 000000000000..28a11ba47693 --- /dev/null +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_0/RedissonSingletons.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson.v3_0; + +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonInstrumenterFactory; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonRequest; + +public final class RedissonSingletons { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.redisson-3.0"; + + private static final Instrumenter INSTRUMENTER = + RedissonInstrumenterFactory.createInstrumenter(INSTRUMENTATION_NAME); + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private RedissonSingletons() {} +} diff --git a/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy b/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy new file mode 100644 index 000000000000..6d4b8c115f87 --- /dev/null +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy @@ -0,0 +1,7 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +class RedissonAsyncClientTest extends AbstractRedissonAsyncClientTest { +} diff --git a/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy b/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy new file mode 100644 index 000000000000..ac39d6519a03 --- /dev/null +++ b/instrumentation/redisson/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy @@ -0,0 +1,7 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +class RedissonClientTest extends AbstractRedissonClientTest { +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/build.gradle.kts b/instrumentation/redisson/redisson-3.17/javaagent/build.gradle.kts new file mode 100644 index 000000000000..f3f50e716781 --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +muzzle { + pass { + group.set("org.redisson") + module.set("redisson") + versions.set("[3.17.0,)") + assertInverse.set(true) + } +} + +dependencies { + library("org.redisson:redisson:3.17.0") + + implementation(project(":instrumentation:redisson:redisson-common:javaagent")) + + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + + testInstrumentation(project(":instrumentation:redisson:redisson-3.0:javaagent")) + + testImplementation(project(":instrumentation:redisson:redisson-common:testing")) +} + +tasks.test { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) + usesService(gradle.sharedServices.registrations["testcontainersBuildService"].getService()) +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisCommandDataInstrumentation.java b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisCommandDataInstrumentation.java new file mode 100644 index 000000000000..50bab352a2c1 --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisCommandDataInstrumentation.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson.v3_17; + +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.redisson.CompletableFutureWrapper; +import java.util.concurrent.CompletableFuture; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class RedisCommandDataInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return namedOneOf( + "org.redisson.client.protocol.CommandData", "org.redisson.client.protocol.CommandsData"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isConstructor().and(takesArgument(0, CompletableFuture.class)), + this.getClass().getName() + "$WrapCompletableFutureAdvice"); + } + + @SuppressWarnings("unused") + public static class WrapCompletableFutureAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Argument(value = 0, readOnly = false) CompletableFuture completableFuture) { + completableFuture = CompletableFutureWrapper.wrap(completableFuture); + } + } +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisConnectionInstrumentation.java b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisConnectionInstrumentation.java new file mode 100644 index 000000000000..4a2938f45d5e --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedisConnectionInstrumentation.java @@ -0,0 +1,84 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson.v3_17; + +import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; +import static io.opentelemetry.javaagent.instrumentation.redisson.v3_17.RedissonSingletons.instrumenter; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.redisson.EndOperationListener; +import io.opentelemetry.javaagent.instrumentation.redisson.PromiseWrapper; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonRequest; +import java.net.InetSocketAddress; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.redisson.client.RedisConnection; + +public class RedisConnectionInstrumentation implements TypeInstrumentation { + @Override + public ElementMatcher typeMatcher() { + return named("org.redisson.client.RedisConnection"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isMethod().and(named("send")), this.getClass().getName() + "$SendAdvice"); + } + + @SuppressWarnings("unused") + public static class SendAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.This RedisConnection connection, + @Advice.Argument(0) Object arg, + @Advice.Local("otelRequest") RedissonRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + Context parentContext = currentContext(); + InetSocketAddress remoteAddress = (InetSocketAddress) connection.getChannel().remoteAddress(); + request = RedissonRequest.create(remoteAddress, arg); + PromiseWrapper promise = request.getPromiseWrapper(); + if (promise == null) { + return; + } + if (!instrumenter().shouldStart(parentContext, request)) { + return; + } + + context = instrumenter().start(parentContext, request); + scope = context.makeCurrent(); + + promise.setEndOperationListener(new EndOperationListener<>(instrumenter(), context, request)); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelRequest") RedissonRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (scope == null) { + return; + } + scope.close(); + + if (throwable != null) { + instrumenter().end(context, request, null, throwable); + } + // span ended in EndOperationListener + } + } +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonInstrumentationModule.java b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonInstrumentationModule.java new file mode 100644 index 000000000000..e97df31dcd45 --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonInstrumentationModule.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson.v3_17; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Arrays.asList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(InstrumentationModule.class) +public class RedissonInstrumentationModule extends InstrumentationModule { + + public RedissonInstrumentationModule() { + super("redisson", "redisson-3.17"); + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + return hasClassesNamed("org.redisson.api.RFunction"); + } + + @Override + public List typeInstrumentations() { + return asList(new RedisConnectionInstrumentation(), new RedisCommandDataInstrumentation()); + } +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonSingletons.java b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonSingletons.java new file mode 100644 index 000000000000..fe5b37b13823 --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/v3_17/RedissonSingletons.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson.v3_17; + +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonInstrumenterFactory; +import io.opentelemetry.javaagent.instrumentation.redisson.RedissonRequest; + +public final class RedissonSingletons { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.redisson-3.17"; + + private static final Instrumenter INSTRUMENTER = + RedissonInstrumenterFactory.createInstrumenter(INSTRUMENTATION_NAME); + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private RedissonSingletons() {} +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy b/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy new file mode 100644 index 000000000000..af0876acb7cb --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy @@ -0,0 +1,12 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +class RedissonAsyncClientTest extends AbstractRedissonAsyncClientTest { + + @Override + boolean useRedisProtocol() { + true + } +} diff --git a/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonClientTest.groovy b/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonClientTest.groovy new file mode 100644 index 000000000000..54e2b5850bd3 --- /dev/null +++ b/instrumentation/redisson/redisson-3.17/javaagent/src/test/groovy/RedissonClientTest.groovy @@ -0,0 +1,12 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +class RedissonClientTest extends AbstractRedissonClientTest { + + @Override + boolean useRedisProtocol() { + true + } +} diff --git a/instrumentation/redisson/redisson-common/javaagent/build.gradle.kts b/instrumentation/redisson/redisson-common/javaagent/build.gradle.kts new file mode 100644 index 000000000000..3328b21686c0 --- /dev/null +++ b/instrumentation/redisson/redisson-common/javaagent/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +dependencies { + compileOnly("org.redisson:redisson:3.0.0") + + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") +} diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/CompletableFutureWrapper.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/CompletableFutureWrapper.java similarity index 100% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/CompletableFutureWrapper.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/CompletableFutureWrapper.java diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java similarity index 58% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java index 17b2d28a982d..d05a8b9f555b 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java +++ b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java @@ -5,22 +5,24 @@ package io.opentelemetry.javaagent.instrumentation.redisson; -import static io.opentelemetry.javaagent.instrumentation.redisson.RedissonSingletons.instrumenter; - import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.util.function.BiConsumer; public final class EndOperationListener implements BiConsumer { + private final Instrumenter instrumenter; private final Context context; private final RedissonRequest request; - public EndOperationListener(Context context, RedissonRequest request) { + public EndOperationListener( + Instrumenter instrumenter, Context context, RedissonRequest request) { + this.instrumenter = instrumenter; this.context = context; this.request = request; } @Override public void accept(T t, Throwable error) { - instrumenter().end(context, request, null, error); + instrumenter.end(context, request, null, error); } } diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/PromiseWrapper.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/PromiseWrapper.java similarity index 100% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/PromiseWrapper.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/PromiseWrapper.java diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonDbAttributesGetter.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonDbAttributesGetter.java similarity index 100% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonDbAttributesGetter.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonDbAttributesGetter.java diff --git a/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumenterFactory.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumenterFactory.java new file mode 100644 index 000000000000..0d105692a04f --- /dev/null +++ b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonInstrumenterFactory.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.redisson; + +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.DbClientAttributesExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; + +public final class RedissonInstrumenterFactory { + + public static Instrumenter createInstrumenter(String instrumentationName) { + RedissonDbAttributesGetter dbAttributesGetter = new RedissonDbAttributesGetter(); + RedissonNetAttributesGetter netAttributesGetter = new RedissonNetAttributesGetter(); + + return Instrumenter.builder( + GlobalOpenTelemetry.get(), + instrumentationName, + DbClientSpanNameExtractor.create(dbAttributesGetter)) + .addAttributesExtractor(DbClientAttributesExtractor.create(dbAttributesGetter)) + .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) + .newInstrumenter(SpanKindExtractor.alwaysClient()); + } + + private RedissonInstrumenterFactory() {} +} diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonNetAttributesGetter.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonNetAttributesGetter.java similarity index 100% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonNetAttributesGetter.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonNetAttributesGetter.java diff --git a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java similarity index 95% rename from instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java rename to instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java index 4481aea1488f..828fde96db08 100644 --- a/instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java +++ b/instrumentation/redisson/redisson-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java @@ -23,7 +23,6 @@ import javax.annotation.Nullable; import org.redisson.client.protocol.CommandData; import org.redisson.client.protocol.CommandsData; -import org.redisson.misc.RPromise; @AutoValue public abstract class RedissonRequest { @@ -138,9 +137,12 @@ private CompletionStage getPromise() { private static MethodHandle findGetPromiseMethod(Class commandClass) { MethodHandles.Lookup lookup = MethodHandles.publicLookup(); try { + Class promiseClass = + Class.forName( + "org.redisson.misc.RPromise", false, RedissonRequest.class.getClassLoader()); // try versions older than 3.16.8 - return lookup.findVirtual(commandClass, "getPromise", MethodType.methodType(RPromise.class)); - } catch (NoSuchMethodException e) { + return lookup.findVirtual(commandClass, "getPromise", MethodType.methodType(promiseClass)); + } catch (NoSuchMethodException | ClassNotFoundException e) { // in 3.16.8 CommandsData#getPromise() and CommandData#getPromise() return type was changed in // a backwards-incompatible way from RPromise to CompletableFuture try { diff --git a/instrumentation/redisson/redisson-common/testing/build.gradle.kts b/instrumentation/redisson/redisson-common/testing/build.gradle.kts new file mode 100644 index 000000000000..e730646c7981 --- /dev/null +++ b/instrumentation/redisson/redisson-common/testing/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("otel.java-conventions") +} + +dependencies { + api(project(":testing-common")) + + implementation("org.apache.groovy:groovy") + implementation("io.opentelemetry:opentelemetry-api") + implementation("org.spockframework:spock-core") + implementation("org.testcontainers:testcontainers") + + compileOnly("org.redisson:redisson:3.0.0") +} diff --git a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy b/instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonAsyncClientTest.groovy similarity index 95% rename from instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy rename to instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonAsyncClientTest.groovy index 9c9dd0710b63..9849b7db21b0 100644 --- a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy +++ b/instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonAsyncClientTest.groovy @@ -8,6 +8,7 @@ import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import java.util.concurrent.Callable import java.util.concurrent.CompletionStage +import java.util.concurrent.TimeUnit import org.redisson.Redisson import org.redisson.api.RBucket import org.redisson.api.RFuture @@ -19,12 +20,10 @@ import org.redisson.config.SingleServerConfig import org.testcontainers.containers.GenericContainer import spock.lang.Shared -import java.util.concurrent.TimeUnit - import static io.opentelemetry.api.trace.SpanKind.CLIENT import static io.opentelemetry.api.trace.SpanKind.INTERNAL -class RedissonAsyncClientTest extends AgentInstrumentationSpecification { +abstract class AbstractRedissonAsyncClientTest extends AgentInstrumentationSpecification { private static GenericContainer redisServer = new GenericContainer<>("redis:6.2.3-alpine").withExposedPorts(6379) @Shared @@ -39,7 +38,7 @@ class RedissonAsyncClientTest extends AgentInstrumentationSpecification { redisServer.start() port = redisServer.getMappedPort(6379) address = "localhost:" + port - if (Boolean.getBoolean("testLatestDeps")) { + if (useRedisProtocol()) { // Newer versions of redisson require scheme, older versions forbid it address = "redis://" + address } @@ -61,6 +60,10 @@ class RedissonAsyncClientTest extends AgentInstrumentationSpecification { clearExportedData() } + boolean useRedisProtocol() { + return Boolean.getBoolean("testLatestDeps") + } + def "test future set"() { when: RBucket keyObject = redisson.getBucket("foo") diff --git a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy b/instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonClientTest.groovy similarity index 97% rename from instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy rename to instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonClientTest.groovy index 817a000339ac..98722e2f6f05 100644 --- a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy +++ b/instrumentation/redisson/redisson-common/testing/src/main/groovy/AbstractRedissonClientTest.groovy @@ -24,7 +24,7 @@ import static io.opentelemetry.api.trace.SpanKind.CLIENT import static java.util.regex.Pattern.compile import static java.util.regex.Pattern.quote -class RedissonClientTest extends AgentInstrumentationSpecification { +abstract class AbstractRedissonClientTest extends AgentInstrumentationSpecification { private static GenericContainer redisServer = new GenericContainer<>("redis:6.2.3-alpine").withExposedPorts(6379) @Shared @@ -39,7 +39,7 @@ class RedissonClientTest extends AgentInstrumentationSpecification { redisServer.start() port = redisServer.getMappedPort(6379) address = "localhost:" + port - if (Boolean.getBoolean("testLatestDeps")) { + if (useRedisProtocol()) { // Newer versions of redisson require scheme, older versions forbid it address = "redis://" + address } @@ -60,6 +60,10 @@ class RedissonClientTest extends AgentInstrumentationSpecification { clearExportedData() } + boolean useRedisProtocol() { + return Boolean.getBoolean("testLatestDeps") + } + def "test string command"() { when: RBucket keyObject = redisson.getBucket("foo") diff --git a/settings.gradle.kts b/settings.gradle.kts index e05efbc38471..aa2f0aac9264 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -365,7 +365,10 @@ include(":instrumentation:reactor:reactor-3.1:testing") include(":instrumentation:reactor:reactor-netty:reactor-netty-0.9:javaagent") include(":instrumentation:reactor:reactor-netty:reactor-netty-1.0:javaagent") include(":instrumentation:rediscala-1.8:javaagent") -include(":instrumentation:redisson-3.0:javaagent") +include(":instrumentation:redisson:redisson-3.0:javaagent") +include(":instrumentation:redisson:redisson-3.17:javaagent") +include(":instrumentation:redisson:redisson-common:javaagent") +include(":instrumentation:redisson:redisson-common:testing") include(":instrumentation:restlet:restlet-1.0:javaagent") include(":instrumentation:restlet:restlet-1.0:library") include(":instrumentation:restlet:restlet-1.0:testing")