Improve rediscala instrumentation (#10301)

This commit is contained in:
Lauri Tulmin 2024-01-23 21:47:12 +02:00 committed by GitHub
parent 87f6be691e
commit 14d1f4c2e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 13 deletions

View File

@ -44,12 +44,19 @@ muzzle {
versions.set("[1.9.0,)") versions.set("[1.9.0,)")
assertInverse.set(true) assertInverse.set(true)
} }
pass {
group.set("io.github.rediscala")
module.set("rediscala_2.13")
versions.set("[1.10.0,)")
assertInverse.set(true)
}
} }
dependencies { dependencies {
library("com.github.etaty:rediscala_2.11:1.8.0") library("com.github.etaty:rediscala_2.11:1.8.0")
latestDepTestLibrary("com.github.etaty:rediscala_2.13:+") latestDepTestLibrary("io.github.rediscala:rediscala_2.13:+")
} }
tasks { tasks {

View File

@ -23,7 +23,11 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
import redis.ActorRequest;
import redis.BufferedRequest;
import redis.RedisCommand; import redis.RedisCommand;
import redis.Request;
import redis.RoundRobinPoolRequest;
import scala.concurrent.ExecutionContext; import scala.concurrent.ExecutionContext;
import scala.concurrent.Future; import scala.concurrent.Future;
@ -74,11 +78,11 @@ public class RequestInstrumentation implements TypeInstrumentation {
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void onExit( public static void onExit(
@Advice.This Object action,
@Advice.Argument(0) RedisCommand<?, ?> cmd, @Advice.Argument(0) RedisCommand<?, ?> cmd,
@Advice.Local("otelContext") Context context, @Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope, @Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable, @Advice.Thrown Throwable throwable,
@Advice.FieldValue("executionContext") ExecutionContext ctx,
@Advice.Return(readOnly = false) Future<Object> responseFuture) { @Advice.Return(readOnly = false) Future<Object> responseFuture) {
if (scope == null) { if (scope == null) {
@ -86,6 +90,17 @@ public class RequestInstrumentation implements TypeInstrumentation {
} }
scope.close(); scope.close();
ExecutionContext ctx = null;
if (action instanceof ActorRequest) {
ctx = ((ActorRequest) action).executionContext();
} else if (action instanceof Request) {
ctx = ((Request) action).executionContext();
} else if (action instanceof BufferedRequest) {
ctx = ((BufferedRequest) action).executionContext();
} else if (action instanceof RoundRobinPoolRequest) {
ctx = ((RoundRobinPoolRequest) action).executionContext();
}
if (throwable != null) { if (throwable != null) {
instrumenter().end(context, cmd, null, throwable); instrumenter().end(context, cmd, null, throwable);
} else { } else {

View File

@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import akka.actor.ActorSystem
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.semconv.SemanticAttributes import io.opentelemetry.semconv.SemanticAttributes
import org.testcontainers.containers.GenericContainer import org.testcontainers.containers.GenericContainer
@ -26,7 +25,7 @@ class RediscalaClientTest extends AgentInstrumentationSpecification {
int port int port
@Shared @Shared
ActorSystem system def system
@Shared @Shared
RedisClient redisClient RedisClient redisClient
@ -34,15 +33,36 @@ class RediscalaClientTest extends AgentInstrumentationSpecification {
def setupSpec() { def setupSpec() {
redisServer.start() redisServer.start()
port = redisServer.getMappedPort(6379) port = redisServer.getMappedPort(6379)
system = ActorSystem.create() // latest has separate artifacts for akka an pekko, currently latestDepTestLibrary picks the
redisClient = new RedisClient("localhost", // pekko one
port, try {
Option.apply(null), def clazz = Class.forName("akka.actor.ActorSystem")
Option.apply(null), system = clazz.getMethod("create").invoke(null)
"RedisClient", } catch (ClassNotFoundException exception) {
Option.apply(null), def clazz = Class.forName("org.apache.pekko.actor.ActorSystem")
system, system = clazz.getMethod("create").invoke(null)
new RedisDispatcher("rediscala.rediscala-client-worker-dispatcher")) }
// latest RedisClient constructor takes username as argument
if (RedisClient.metaClass.getMetaMethod("username") != null) {
redisClient = new RedisClient("localhost",
port,
Option.apply(null),
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
new RedisDispatcher("rediscala.rediscala-client-worker-dispatcher"))
} else {
redisClient = new RedisClient("localhost",
port,
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
new RedisDispatcher("rediscala.rediscala-client-worker-dispatcher"))
}
} }
def cleanupSpec() { def cleanupSpec() {