End redisson span when the operation actually ends
ADD
instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/EndOperationListener.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.redisson;
+
+import static io.opentelemetry.javaagent.instrumentation.redisson.RedissonSingletons.instrumenter;
+
+import io.netty.util.concurrent.Future;
+import io.opentelemetry.context.Context;
+import java.util.function.BiConsumer;
+
+public final class EndOperationListener<T> implements BiConsumer<T, Throwable> {
+ private final Context context;
+ private final RedissonRequest request;
+
+ public EndOperationListener(Context context, RedissonRequest request) {
+ this.context = context;
+ this.request = request;
+ }
+
+ public void operationComplete(Future<T> future) {
+ instrumenter().end(context, request, null, future.cause());
+ }
+
+ @Override
+ public void accept(T t, Throwable error) {
+ instrumenter().end(context, request, null, error);
+ }
+}

MODIFY
instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisConnectionInstrumentation.java
instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedisConnectionInstrumentation.java
@@ -19,6 +19,7 @@ import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.redisson.client.RedisConnection;
+import org.redisson.misc.RPromise;
public class RedisConnectionInstrumentation implements TypeInstrumentation {
@Override
@@ -39,7 +40,7 @@ public class RedisConnectionInstrumentation implements TypeInstrumentation {
public static void onEnter(
@Advice.This RedisConnection connection,
@Advice.Argument(0) Object arg,
- @Advice.Local("otelRedissonRequest") RedissonRequest request,
+ @Advice.Local("otelRequest") RedissonRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
Context parentContext = currentContext();
@@ -56,15 +57,22 @@ public class RedisConnectionInstrumentation implements TypeInstrumentation {
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
- @Advice.Local("otelRedissonRequest") RedissonRequest request,
+ @Advice.Local("otelRequest") RedissonRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
+
if (scope == null) {
return;
}
-
scope.close();
+
+ RPromise<?> promise = request.getPromise();
+ if (promise == null || throwable != null) {
instrumenter().end(context, request, null, throwable);
+ } else {
+ // span ended in EndOperationListener
+ promise.whenComplete(new EndOperationListener<>(context, request));
+ }
}
}
}

MODIFY
instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java
instrumentation/redisson-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/RedissonRequest.java
@@ -15,8 +15,10 @@ import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
+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 {
@@ -29,6 +31,7 @@ public abstract class RedissonRequest {
public abstract Object getCommand();
+ @Nullable
public String getOperation() {
Object command = getCommand();
if (command instanceof CommandData) {
@@ -42,6 +45,7 @@ public abstract class RedissonRequest {
return null;
}
+ @Nullable
public String getStatement() {
List<String> sanitizedStatements = sanitizeStatement();
switch (sanitizedStatements.size()) {
@@ -92,4 +96,15 @@ public abstract class RedissonRequest {
}
return RedisCommandSanitizer.sanitize(command.getCommand().getName(), args);
}
+
+ @Nullable
+ public RPromise<?> getPromise() {
+ Object command = getCommand();
+ if (command instanceof CommandData) {
+ return ((CommandData<?, ?>) command).getPromise();
+ } else if (command instanceof CommandsData) {
+ return ((CommandsData) command).getPromise();
+ }
+ return null;
+ }
}

End redisson span when the operation actually ends (#5073)