From ebfcd841d717d3f59952420693942bd52361096d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 1 Sep 2025 16:03:18 +0200 Subject: [PATCH 01/16] vertx-http-client-3.0 --- .../client/HttpClientImplInstrumentation.java | 4 +- .../HttpRequestImplInstrumentation.java | 21 ++-- .../client/HttpRequestInstrumentation.java | 116 +++++++++--------- .../VertxClientInstrumentationModule.java | 9 +- .../v3_0/client/VertxClientSingletons.java | 13 ++ 5 files changed, 93 insertions(+), 70 deletions(-) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpClientImplInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpClientImplInstrumentation.java index f36c3fdd4474..dd20f8eee754 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpClientImplInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpClientImplInstrumentation.java @@ -5,10 +5,10 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client; +import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.HTTP_CLIENT_OPTIONS; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import static net.bytebuddy.matcher.ElementMatchers.named; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.http.HttpClientOptions; @@ -36,7 +36,7 @@ public static class AttachStateAdvice { public static void attachHttpClientOptions( @Advice.This HttpClientImpl client, @Advice.FieldValue("options") HttpClientOptions options) { - VirtualField.find(HttpClientImpl.class, HttpClientOptions.class).set(client, options); + HTTP_CLIENT_OPTIONS.set(client, options); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestImplInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestImplInstrumentation.java index 1b720657ecc6..c65b8136d376 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestImplInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestImplInstrumentation.java @@ -5,11 +5,12 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client; +import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.HTTP_CLIENT_OPTIONS; +import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.REQUEST_INFO; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.http.HttpClientOptions; @@ -53,13 +54,11 @@ public static void attachRequestInfo( @Advice.Argument(0) HttpClientImpl client, @Advice.Argument(2) String host, @Advice.Argument(3) int port) { - HttpClientOptions httpClientOptions = - VirtualField.find(HttpClientImpl.class, HttpClientOptions.class).get(client); - VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class) - .set( - request, - VertxRequestInfo.create( - httpClientOptions != null && httpClientOptions.isSsl(), host, port)); + HttpClientOptions httpClientOptions = HTTP_CLIENT_OPTIONS.get(client); + REQUEST_INFO.set( + request, + VertxRequestInfo.create( + httpClientOptions != null && httpClientOptions.isSsl(), host, port)); } } @@ -71,8 +70,7 @@ public static void attachRequestInfo( @Advice.Argument(1) boolean ssl, @Advice.Argument(3) String host, @Advice.Argument(4) int port) { - VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class) - .set(request, VertxRequestInfo.create(ssl, host, port)); + REQUEST_INFO.set(request, VertxRequestInfo.create(ssl, host, port)); } } @@ -84,8 +82,7 @@ public static void attachRequestInfo( @Advice.Argument(1) boolean ssl, @Advice.Argument(4) String host, @Advice.Argument(5) int port) { - VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class) - .set(request, VertxRequestInfo.create(ssl, host, port)); + REQUEST_INFO.set(request, VertxRequestInfo.create(ssl, host, port)); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java index 5590b393ec35..84c406974da9 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java @@ -7,6 +7,8 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.CONTEXTS; +import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.REQUEST_INFO; import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPrivate; @@ -16,7 +18,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -25,7 +26,10 @@ import io.vertx.core.Handler; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -83,41 +87,47 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class EndRequestAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void attachContext( - @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + public static class AdviceScope { + private final Context context; + private final Scope scope; + + public AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; + } + + public void end(@Nullable Throwable throwable, HttpClientRequest request) { + scope.close(); + if (throwable != null) { + instrumenter().end(context, request, null, throwable); + } + } + } - VertxRequestInfo requestInfo = - VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class).get(request); + @Nullable + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope attachContext(@Advice.This HttpClientRequest request) { + VertxRequestInfo requestInfo = REQUEST_INFO.get(request); if (requestInfo == null) { - return; + return null; } Context parentContext = Java8BytecodeBridge.currentContext(); if (!instrumenter().shouldStart(parentContext, request)) { - return; + return null; } - - context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); - - scope = context.makeCurrent(); + Context context = instrumenter().start(parentContext, request); + CONTEXTS.set(request, new Contexts(parentContext, context)); + return new AdviceScope(context, context.makeCurrent()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endScope( @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Thrown Throwable throwable) { - if (scope != null) { - scope.close(); - } - if (throwable != null) { - instrumenter().end(context, request, null, throwable); + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + adviceScope.end(throwable, request); } } } @@ -125,25 +135,23 @@ public static void endScope( @SuppressWarnings("unused") public static class HandleExceptionAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleException( - @Advice.This HttpClientRequest request, - @Advice.Argument(0) Throwable t, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope handleException( + @Advice.This HttpClientRequest request, @Advice.Argument(0) Throwable t) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } - instrumenter().end(contexts.context, request, null, t); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -153,25 +161,23 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class HandleResponseAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleResponseEnter( - @Advice.This HttpClientRequest request, - @Advice.Argument(0) HttpClientResponse response, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope handleResponseEnter( + @Advice.This HttpClientRequest request, @Advice.Argument(0) HttpClientResponse response) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } - instrumenter().end(contexts.context, request, response, null); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -181,19 +187,18 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class MountContextAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void mountContext( - @Advice.This HttpClientRequest request, @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope mountContext(@Advice.This HttpClientRequest request) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } - - scope = contexts.context.makeCurrent(); + return contexts.context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void unmountContext(@Advice.Local("otelScope") Scope scope) { + public static void unmountContext(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -203,15 +208,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class ExceptionHandlerAdvice { + @Nullable + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapExceptionHandler( + public static Handler wrapExceptionHandler( @Advice.This HttpClientRequest request, - @Advice.Argument(value = 0, readOnly = false) Handler handler) { - if (handler != null) { - VirtualField virtualField = - VirtualField.find(HttpClientRequest.class, Contexts.class); - handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler); + @Advice.Argument(0) @Nullable Handler handler) { + if (handler == null) { + return null; } + return ExceptionHandlerWrapper.wrap(instrumenter(), request, CONTEXTS, handler); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientInstrumentationModule.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientInstrumentationModule.java index ecbb82a9bf4a..e36e65b91c43 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class VertxClientInstrumentationModule extends InstrumentationModule { +public class VertxClientInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxClientInstrumentationModule() { super("vertx-http-client", "vertx-http-client-3.0", "vertx"); @@ -34,4 +36,9 @@ public List typeInstrumentations() { new HttpRequestImplInstrumentation(), new HttpRequestInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java index 9153de8e39b7..ec46f53ba669 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java @@ -6,9 +6,13 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.util.VirtualField; +import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; import io.opentelemetry.javaagent.instrumentation.vertx.client.VertxClientInstrumenterFactory; +import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; +import io.vertx.core.http.impl.HttpClientImpl; public final class VertxClientSingletons { @@ -16,6 +20,15 @@ public final class VertxClientSingletons { VertxClientInstrumenterFactory.create( "io.opentelemetry.vertx-http-client-3.0", new Vertx3HttpAttributesGetter()); + public static final VirtualField CONTEXTS = + VirtualField.find(HttpClientRequest.class, Contexts.class); + + public static final VirtualField REQUEST_INFO = + VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class); + + public static final VirtualField HTTP_CLIENT_OPTIONS = + VirtualField.find(HttpClientImpl.class, HttpClientOptions.class); + public static Instrumenter instrumenter() { return INSTRUMENTER; } From d69c081527cd45cf70b86a2b8a02fa1ec4869e45 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 10:25:01 +0200 Subject: [PATCH 02/16] vertx-http-client-4.0 --- .../ConnectionManagerInstrumentation.java | 24 ++-- .../vertx/v4_0/client/HandlerWrapper.java | 4 +- .../HttpClientConnectionInstrumentation.java | 8 +- .../client/HttpRequestInstrumentation.java | 105 ++++++++++-------- .../VertxClientInstrumentationModule.java | 9 +- .../v4_0/client/VertxClientSingletons.java | 5 + 6 files changed, 95 insertions(+), 60 deletions(-) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/ConnectionManagerInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/ConnectionManagerInstrumentation.java index 9b51318b2b78..67fbb9702035 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/ConnectionManagerInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/ConnectionManagerInstrumentation.java @@ -12,7 +12,10 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.Handler; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -42,28 +45,31 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class GetConnectionArg2Advice { + @Nullable + @AssignReturned.ToArguments(@ToArgument(2)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 2, readOnly = false) Handler handler) { - handler = HandlerWrapper.wrap(handler); + public static Handler wrapHandler(@Advice.Argument(2) @Nullable Handler handler) { + return HandlerWrapper.wrap(handler); } } @SuppressWarnings("unused") public static class GetConnectionArg3Advice { + @Nullable + @AssignReturned.ToArguments(@ToArgument(3)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 3, readOnly = false) Handler handler) { - handler = HandlerWrapper.wrap(handler); + public static Handler wrapHandler(@Advice.Argument(3) @Nullable Handler handler) { + return HandlerWrapper.wrap(handler); } } @SuppressWarnings("unused") public static class GetConnectionArg4Advice { + @Nullable + @AssignReturned.ToArguments(@ToArgument(4)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 4, readOnly = false) Handler handler) { - handler = HandlerWrapper.wrap(handler); + public static Handler wrapHandler(@Advice.Argument(4) @Nullable Handler handler) { + return HandlerWrapper.wrap(handler); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HandlerWrapper.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HandlerWrapper.java index a2938d0e8e68..794ad982a31b 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HandlerWrapper.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HandlerWrapper.java @@ -8,6 +8,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import io.vertx.core.Handler; +import javax.annotation.Nullable; public class HandlerWrapper implements Handler { private final Handler delegate; @@ -18,7 +19,8 @@ private HandlerWrapper(Handler delegate, Context context) { this.context = context; } - public static Handler wrap(Handler handler) { + @Nullable + public static Handler wrap(@Nullable Handler handler) { Context current = Context.current(); if (handler != null && !(handler instanceof HandlerWrapper) && current != Context.root()) { handler = new HandlerWrapper<>(handler, current); diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpClientConnectionInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpClientConnectionInstrumentation.java index b310f747f38d..636b40d7d713 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpClientConnectionInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpClientConnectionInstrumentation.java @@ -14,6 +14,8 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.Handler; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -39,10 +41,10 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class CreateStreamAdvice { + @AssignReturned.ToArguments(@ToArgument(1)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 1, readOnly = false) Handler handler) { - handler = HandlerWrapper.wrap(handler); + public static Handler wrapHandler(@Advice.Argument(1) Handler handler) { + return HandlerWrapper.wrap(handler); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java index fb2b8a0895f4..2005ccd9df3a 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java @@ -7,6 +7,7 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client.VertxClientSingletons.CONTEXTS; import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client.VertxClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPrivate; @@ -16,7 +17,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -25,7 +25,10 @@ import io.vertx.core.Handler; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -85,35 +88,46 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class EndRequestAdvice { + public static class AdviceScope { + public final Context context; + public final Scope scope; + + public AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; + } + + public void end(HttpClientRequest request, Throwable throwable) { + scope.close(); + if (throwable != null) { + instrumenter().end(context, request, null, throwable); + } + } + } + + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void attachContext( - @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - Context parentContext = Java8BytecodeBridge.currentContext(); + public static AdviceScope attachContext(@Advice.This HttpClientRequest request) { + Context parentContext = Java8BytecodeBridge.currentContext(); if (!instrumenter().shouldStart(parentContext, request)) { - return; + return null; } - context = instrumenter().start(parentContext, request); + Context context = instrumenter().start(parentContext, request); Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); + CONTEXTS.set(request, contexts); - scope = context.makeCurrent(); + return new AdviceScope(context, context.makeCurrent()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endScope( @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Thrown Throwable throwable) { - if (scope != null) { - scope.close(); - } - if (throwable != null) { - instrumenter().end(context, request, null, throwable); + @Advice.Thrown Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + adviceScope.end(request, throwable); } } } @@ -121,25 +135,24 @@ public static void endScope( @SuppressWarnings("unused") public static class HandleExceptionAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleException( - @Advice.This HttpClientRequest request, - @Advice.Argument(0) Throwable t, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope handleException( + @Advice.This HttpClientRequest request, @Advice.Argument(0) Throwable t) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } instrumenter().end(contexts.context, request, null, t); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -149,25 +162,24 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class HandleResponseAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleResponseEnter( - @Advice.This HttpClientRequest request, - @Advice.Argument(1) HttpClientResponse response, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope handleResponseEnter( + @Advice.This HttpClientRequest request, @Advice.Argument(1) HttpClientResponse response) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } instrumenter().end(contexts.context, request, response, null); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -177,19 +189,19 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class MountContextAdvice { + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void mountContext( - @Advice.This HttpClientRequest request, @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope mountContext(@Advice.This HttpClientRequest request) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } - scope = contexts.context.makeCurrent(); + return contexts.context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void unmountContext(@Advice.Local("otelScope") Scope scope) { + public static void unmountContext(@Advice.Enter @Nullable Scope scope) { if (scope != null) { scope.close(); } @@ -199,15 +211,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class ExceptionHandlerAdvice { + @Nullable + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapExceptionHandler( + public static Handler wrapExceptionHandler( @Advice.This HttpClientRequest request, - @Advice.Argument(value = 0, readOnly = false) Handler handler) { - if (handler != null) { - VirtualField virtualField = - VirtualField.find(HttpClientRequest.class, Contexts.class); - handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler); + @Advice.Argument(0) @Nullable Handler handler) { + if (handler == null) { + return null; } + return ExceptionHandlerWrapper.wrap(instrumenter(), request, CONTEXTS, handler); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientInstrumentationModule.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientInstrumentationModule.java index c18687d452a9..a3b4c24e8a25 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientInstrumentationModule.java @@ -12,11 +12,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class VertxClientInstrumentationModule extends InstrumentationModule { +public class VertxClientInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxClientInstrumentationModule() { super("vertx-http-client", "vertx-http-client-4.0", "vertx"); @@ -37,4 +39,9 @@ public List typeInstrumentations() { new HttpClientConnectionInstrumentation(), new HttpRequestInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java index 1e14fa9f4f44..8960551fb916 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java @@ -6,6 +6,8 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.util.VirtualField; +import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; import io.opentelemetry.javaagent.instrumentation.vertx.client.VertxClientInstrumenterFactory; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; @@ -16,6 +18,9 @@ public final class VertxClientSingletons { VertxClientInstrumenterFactory.create( "io.opentelemetry.vertx-http-client-4.0", new Vertx4HttpAttributesGetter()); + public static final VirtualField CONTEXTS = + VirtualField.find(HttpClientRequest.class, Contexts.class); + public static Instrumenter instrumenter() { return INSTRUMENTER; } From 8cd26889705b71a3a0901b2fa03a1f05ac399a8b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 10:50:12 +0200 Subject: [PATCH 03/16] vertx-http-client-5.0 --- .../client/HttpRequestInstrumentation.java | 108 ++++++++++-------- .../ResourceManagerInstrumentation.java | 6 +- .../VertxClientInstrumentationModule.java | 9 +- .../v5_0/client/VertxClientSingletons.java | 4 + 4 files changed, 75 insertions(+), 52 deletions(-) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java index c1d579a8c5bf..c174785a2689 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java @@ -7,6 +7,7 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.client.VertxClientSingletons.CONTEXTS; import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.client.VertxClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPrivate; @@ -16,7 +17,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -25,7 +25,10 @@ import io.vertx.core.Handler; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -85,35 +88,47 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class EndRequestAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void attachContext( - @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - Context parentContext = Java8BytecodeBridge.currentContext(); + public static class AdviceScope { + private final Context context; + private final Scope scope; + + private AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; + } - if (!instrumenter().shouldStart(parentContext, request)) { - return; + @Nullable + public static AdviceScope startAndAttachContext(HttpClientRequest request) { + Context parentContext = Java8BytecodeBridge.currentContext(); + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } + Context context = instrumenter().start(parentContext, request); + CONTEXTS.set(request, new Contexts(parentContext, context)); + return new AdviceScope(context, context.makeCurrent()); } - context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); + public void end(HttpClientRequest request, @Nullable Throwable throwable) { + scope.close(); + if (throwable != null) { + instrumenter().end(context, request, null, throwable); + } + } + } - scope = context.makeCurrent(); + @Nullable + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope attachContext(@Advice.This HttpClientRequest request) { + return AdviceScope.startAndAttachContext(request); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endScope( @Advice.This HttpClientRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Thrown Throwable throwable) { - if (scope != null) { - scope.close(); - } - if (throwable != null) { - instrumenter().end(context, request, null, throwable); + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + adviceScope.end(request, throwable); } } } @@ -122,24 +137,21 @@ public static void endScope( public static class HandleExceptionAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleException( - @Advice.This HttpClientRequest request, - @Advice.Argument(0) Throwable t, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); - + public static Scope handleException( + @Advice.This HttpClientRequest request, @Advice.Argument(0) Throwable t) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } instrumenter().end(contexts.context, request, null, t); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter Scope scope) { if (scope != null) { scope.close(); } @@ -150,24 +162,22 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { public static class HandleResponseAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void handleResponseEnter( - @Advice.This HttpClientRequest request, - @Advice.Argument(1) HttpClientResponse response, - @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope handleResponseEnter( + @Advice.This HttpClientRequest request, @Advice.Argument(1) HttpClientResponse response) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } instrumenter().end(contexts.context, request, response, null); // Scoping all potential callbacks etc to the parent context - scope = contexts.parentContext.makeCurrent(); + return contexts.parentContext.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { + public static void handleResponseExit(@Advice.Enter Scope scope) { if (scope != null) { scope.close(); } @@ -178,18 +188,17 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) { public static class MountContextAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void mountContext( - @Advice.This HttpClientRequest request, @Advice.Local("otelScope") Scope scope) { - Contexts contexts = VirtualField.find(HttpClientRequest.class, Contexts.class).get(request); + public static Scope mountContext(@Advice.This HttpClientRequest request) { + Contexts contexts = CONTEXTS.get(request); if (contexts == null) { - return; + return null; } - scope = contexts.context.makeCurrent(); + return contexts.context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void unmountContext(@Advice.Local("otelScope") Scope scope) { + public static void unmountContext(@Advice.Enter Scope scope) { if (scope != null) { scope.close(); } @@ -199,15 +208,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) { @SuppressWarnings("unused") public static class ExceptionHandlerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapExceptionHandler( + public static Handler wrapExceptionHandler( @Advice.This HttpClientRequest request, - @Advice.Argument(value = 0, readOnly = false) Handler handler) { + @Advice.Argument(0) Handler originalHandler) { + Handler handler = originalHandler; if (handler != null) { - VirtualField virtualField = - VirtualField.find(HttpClientRequest.class, Contexts.class); - handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler); + handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, CONTEXTS, handler); } + return handler; } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/ResourceManagerInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/ResourceManagerInstrumentation.java index 9f7d18efbf25..79a6e3d472e2 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/ResourceManagerInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/ResourceManagerInstrumentation.java @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.Future; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -32,9 +33,10 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WithResourceAsyncAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void wrapFuture(@Advice.Return(readOnly = false) Future future) { - future = VertxClientSingletons.wrapFuture(future); + public static Future wrapFuture(@Advice.Return Future future) { + return VertxClientSingletons.wrapFuture(future); } } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientInstrumentationModule.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientInstrumentationModule.java index 03df65695bee..737a176f26d3 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class VertxClientInstrumentationModule extends InstrumentationModule { +public class VertxClientInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxClientInstrumentationModule() { super("vertx-http-client", "vertx-http-client-5.0", "vertx"); @@ -34,4 +36,9 @@ public List typeInstrumentations() { new HttpClientRequestBaseInstrumentation(), new ResourceManagerInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientSingletons.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientSingletons.java index e7deee794716..215f28b6daf7 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientSingletons.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/VertxClientSingletons.java @@ -9,6 +9,7 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.util.VirtualField; +import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; import io.opentelemetry.javaagent.instrumentation.vertx.client.VertxClientInstrumenterFactory; import io.vertx.core.Future; import io.vertx.core.http.HttpClientRequest; @@ -29,6 +30,9 @@ public static Instrumenter instrumenter() private static final VirtualField authorityField = VirtualField.find(HttpClientRequest.class, HostAndPort.class); + public static final VirtualField CONTEXTS = + VirtualField.find(HttpClientRequest.class, Contexts.class); + public static void setAuthority(HttpClientRequest request, HostAndPort authority) { authorityField.set(request, authority); } From 2f2729528321eed15b1a507a219d262a39882991 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 11:26:13 +0200 Subject: [PATCH 04/16] inline advice scope start --- .../client/HttpRequestInstrumentation.java | 31 ++++++++++-------- .../client/HttpRequestInstrumentation.java | 32 +++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java index 84c406974da9..d55fe9fbffbe 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java @@ -91,11 +91,27 @@ public static class AdviceScope { private final Context context; private final Scope scope; - public AdviceScope(Context context, Scope scope) { + private AdviceScope(Context context, Scope scope) { this.context = context; this.scope = scope; } + @Nullable + public static AdviceScope startAndAttachContext(HttpClientRequest request) { + VertxRequestInfo requestInfo = REQUEST_INFO.get(request); + if (requestInfo == null) { + return null; + } + + Context parentContext = Java8BytecodeBridge.currentContext(); + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } + Context context = instrumenter().start(parentContext, request); + CONTEXTS.set(request, new Contexts(parentContext, context)); + return new AdviceScope(context, context.makeCurrent()); + } + public void end(@Nullable Throwable throwable, HttpClientRequest request) { scope.close(); if (throwable != null) { @@ -107,18 +123,7 @@ public void end(@Nullable Throwable throwable, HttpClientRequest request) { @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) public static AdviceScope attachContext(@Advice.This HttpClientRequest request) { - VertxRequestInfo requestInfo = REQUEST_INFO.get(request); - if (requestInfo == null) { - return null; - } - - Context parentContext = Java8BytecodeBridge.currentContext(); - if (!instrumenter().shouldStart(parentContext, request)) { - return null; - } - Context context = instrumenter().start(parentContext, request); - CONTEXTS.set(request, new Contexts(parentContext, context)); - return new AdviceScope(context, context.makeCurrent()); + return AdviceScope.startAndAttachContext(request); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java index 2005ccd9df3a..e386d8955ed8 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java @@ -89,14 +89,28 @@ public void transform(TypeTransformer transformer) { public static class EndRequestAdvice { public static class AdviceScope { - public final Context context; - public final Scope scope; + private final Context context; + private final Scope scope; - public AdviceScope(Context context, Scope scope) { + private AdviceScope(Context context, Scope scope) { this.context = context; this.scope = scope; } + @Nullable + public static AdviceScope startAndAttachContext(HttpClientRequest request) { + Context parentContext = Java8BytecodeBridge.currentContext(); + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } + + Context context = instrumenter().start(parentContext, request); + Contexts contexts = new Contexts(parentContext, context); + CONTEXTS.set(request, contexts); + + return new AdviceScope(context, context.makeCurrent()); + } + public void end(HttpClientRequest request, Throwable throwable) { scope.close(); if (throwable != null) { @@ -108,17 +122,7 @@ public void end(HttpClientRequest request, Throwable throwable) { @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) public static AdviceScope attachContext(@Advice.This HttpClientRequest request) { - - Context parentContext = Java8BytecodeBridge.currentContext(); - if (!instrumenter().shouldStart(parentContext, request)) { - return null; - } - - Context context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - CONTEXTS.set(request, contexts); - - return new AdviceScope(context, context.makeCurrent()); + return AdviceScope.startAndAttachContext(request); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) From 23a0bc52e45f00382a7f20f6e059697cbb9757dc Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 11:38:14 +0200 Subject: [PATCH 05/16] vertx-kafka-client-3.6 --- .../v3_6/KafkaReadStreamImplInstrumentation.java | 16 ++++++++++------ .../v3_6/VertxKafkaInstrumentationModule.java | 9 ++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/KafkaReadStreamImplInstrumentation.java b/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/KafkaReadStreamImplInstrumentation.java index 24d396cad2bb..fd996020f1bc 100644 --- a/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/KafkaReadStreamImplInstrumentation.java +++ b/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/KafkaReadStreamImplInstrumentation.java @@ -16,6 +16,8 @@ import io.vertx.core.Handler; import io.vertx.kafka.client.consumer.impl.KafkaReadStreamImpl; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; import org.apache.kafka.clients.consumer.ConsumerRecord; @@ -47,24 +49,26 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class HandlerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static Handler> onEnter( @Advice.This KafkaReadStreamImpl readStream, - @Advice.Argument(value = 0, readOnly = false) Handler> handler) { + @Advice.Argument(0) Handler> handler) { - handler = new InstrumentedSingleRecordHandler<>(handler); + return new InstrumentedSingleRecordHandler<>(handler); } } @SuppressWarnings("unused") public static class BatchHandlerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static Handler> onEnter( @Advice.This KafkaReadStreamImpl readStream, - @Advice.Argument(value = 0, readOnly = false) Handler> handler) { + @Advice.Argument(0) Handler> handler) { - handler = new InstrumentedBatchRecordsHandler<>(handler); + return new InstrumentedBatchRecordsHandler<>(handler); } } diff --git a/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/VertxKafkaInstrumentationModule.java b/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/VertxKafkaInstrumentationModule.java index 605351f87ee6..7e2fd2bbb874 100644 --- a/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/VertxKafkaInstrumentationModule.java +++ b/instrumentation/vertx/vertx-kafka-client-3.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/kafka/v3_6/VertxKafkaInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class VertxKafkaInstrumentationModule extends InstrumentationModule { +public class VertxKafkaInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxKafkaInstrumentationModule() { super("vertx-kafka-client", "vertx-kafka-client-3.6", "vertx"); @@ -24,4 +26,9 @@ public List typeInstrumentations() { return asList( new KafkaReadStreamImplInstrumentation(), new KafkaConsumerRecordsImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 014c79cec60b5cd62b6c43537222a01e5c569372 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 11:38:54 +0200 Subject: [PATCH 06/16] vertx-redis-client-4.0 --- ...isStandaloneConnectionInstrumentation.java | 102 +++++++++++------- ...VertxRedisClientInstrumentationModule.java | 5 + 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java index 157a7b2e3677..c7b23869fe44 100644 --- a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java +++ b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java @@ -21,7 +21,9 @@ import io.vertx.redis.client.impl.RedisStandaloneConnection; import io.vertx.redis.client.impl.RedisURI; import io.vertx.redis.client.impl.RequestUtil; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -40,54 +42,80 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SendAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This RedisStandaloneConnection connection, - @Advice.Argument(0) Request request, - @Advice.FieldValue("netSocket") NetSocket netSocket, - @Advice.Local("otelRequest") VertxRedisClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - if (request == null) { - return; - } + public static class AdviceScope { + public VertxRedisClientRequest otelRequest; + public Context context; + public Scope scope; + + @Nullable + public static AdviceScope start( + RedisStandaloneConnection connection, @Nullable Request request, NetSocket netSocket) { - String commandName = VertxRedisClientSingletons.getCommandName(request.command()); - RedisURI redisUri = VertxRedisClientSingletons.getRedisUri(connection); - if (commandName == null || redisUri == null) { - return; + if (request == null) { + return null; + } + + String commandName = VertxRedisClientSingletons.getCommandName(request.command()); + RedisURI redisUri = VertxRedisClientSingletons.getRedisUri(connection); + if (commandName == null || redisUri == null) { + return null; + } + + VertxRedisClientRequest otelRequest = + new VertxRedisClientRequest( + commandName, RequestUtil.getArgs(request), redisUri, netSocket); + Context parentContext = currentContext(); + if (!instrumenter().shouldStart(parentContext, otelRequest)) { + return null; + } + AdviceScope locals = new AdviceScope(); + locals.otelRequest = otelRequest; + locals.context = instrumenter().start(parentContext, locals.otelRequest); + locals.scope = locals.context.makeCurrent(); + return locals; } - otelRequest = - new VertxRedisClientRequest( - commandName, RequestUtil.getArgs(request), redisUri, netSocket); - Context parentContext = currentContext(); - if (!instrumenter().shouldStart(parentContext, otelRequest)) { - return; + @Nullable + public Future end( + @Nullable Future responseFuture, @Nullable Throwable throwable) { + if (scope == null) { + return responseFuture; + } + + scope.close(); + if (throwable != null) { + instrumenter().end(context, otelRequest, null, throwable); + } else { + responseFuture = + VertxRedisClientSingletons.wrapEndSpan(responseFuture, context, otelRequest); + } + return responseFuture; } + } + + @Nullable + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter( + @Advice.This RedisStandaloneConnection connection, + @Advice.Argument(0) @Nullable Request request, + @Advice.FieldValue("netSocket") NetSocket netSocket) { - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); + return AdviceScope.start(connection, request, netSocket); } + @Nullable + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void onExit( + public static Future onExit( @Advice.Thrown Throwable throwable, - @Advice.Return(readOnly = false) Future responseFuture, - @Advice.Local("otelRequest") VertxRedisClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - if (scope == null) { - return; - } + @Advice.Return @Nullable Future responseFuture, + @Advice.Enter @Nullable AdviceScope adviceScope) { - scope.close(); - if (throwable != null) { - instrumenter().end(context, otelRequest, null, throwable); - } else { - responseFuture = - VertxRedisClientSingletons.wrapEndSpan(responseFuture, context, otelRequest); + if (adviceScope != null) { + return adviceScope.end(responseFuture, throwable); } + + return responseFuture; } } diff --git a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/VertxRedisClientInstrumentationModule.java b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/VertxRedisClientInstrumentationModule.java index e3cab6a83ce5..9d7dc5300965 100644 --- a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/VertxRedisClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/VertxRedisClientInstrumentationModule.java @@ -39,4 +39,9 @@ public List typeInstrumentations() { new RedisConnectionProviderInstrumentation(), new CommandImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 7eb2a2ee434c42292a7320256b7465a1ef9e4073 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 11:47:13 +0200 Subject: [PATCH 07/16] vertx-rx-java-3.5 --- .../AsyncResultSingleInstrumentation.java | 18 ++++++++++-------- .../reactive/VertxRxInstrumentationModule.java | 9 ++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/AsyncResultSingleInstrumentation.java b/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/AsyncResultSingleInstrumentation.java index af81b85ffba1..4717f5a9d25c 100644 --- a/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/AsyncResultSingleInstrumentation.java +++ b/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/AsyncResultSingleInstrumentation.java @@ -18,6 +18,8 @@ import io.vertx.core.Handler; import java.util.function.Consumer; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -50,22 +52,22 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class ConstructorWithHandlerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 0, readOnly = false) Handler>> handler) { - handler = - AsyncResultHandlerWrapper.wrapIfNeeded(handler, Java8BytecodeBridge.currentContext()); + public static Handler>> wrapHandler( + @Advice.Argument(0) Handler>> handler) { + return AsyncResultHandlerWrapper.wrapIfNeeded(handler, Java8BytecodeBridge.currentContext()); } } @SuppressWarnings("unused") public static class ConstructorWithConsumerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 0, readOnly = false) Consumer>> handler) { - handler = - AsyncResultConsumerWrapper.wrapIfNeeded(handler, Java8BytecodeBridge.currentContext()); + public static Consumer>> wrapHandler( + @Advice.Argument(0) Consumer>> handler) { + return AsyncResultConsumerWrapper.wrapIfNeeded(handler, Java8BytecodeBridge.currentContext()); } } } diff --git a/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/VertxRxInstrumentationModule.java b/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/VertxRxInstrumentationModule.java index aef5154385cd..b31dc3df8880 100644 --- a/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/VertxRxInstrumentationModule.java +++ b/instrumentation/vertx/vertx-rx-java-3.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/reactive/VertxRxInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class VertxRxInstrumentationModule extends InstrumentationModule { +public class VertxRxInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxRxInstrumentationModule() { super("vertx-rx-java", "vertx-rx-java-3.5", "vertx"); @@ -23,4 +25,9 @@ public VertxRxInstrumentationModule() { public List typeInstrumentations() { return singletonList(new AsyncResultSingleInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 42bdc904b2b0951f552992d1b5a5022ab7cd9720 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 11:53:13 +0200 Subject: [PATCH 08/16] vertx-web-3.0 --- .../instrumentation/vertx/RouteInstrumentation.java | 9 ++++++--- .../vertx/VertxWebInstrumentationModule.java | 9 ++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RouteInstrumentation.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RouteInstrumentation.java index c01649b8c713..8eb5e301669d 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RouteInstrumentation.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RouteInstrumentation.java @@ -16,6 +16,8 @@ import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -40,10 +42,11 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class HandlerAdvice { + @AssignReturned.ToArguments(@ToArgument(0)) @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrapHandler( - @Advice.Argument(value = 0, readOnly = false) Handler handler) { - handler = new RoutingContextHandlerWrapper(handler); + public static Handler wrapHandler( + @Advice.Argument(0) Handler handler) { + return new RoutingContextHandlerWrapper(handler); } } } diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/VertxWebInstrumentationModule.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/VertxWebInstrumentationModule.java index 659c2dfe507a..392bd6ce67cc 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/VertxWebInstrumentationModule.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/VertxWebInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class VertxWebInstrumentationModule extends InstrumentationModule { +public class VertxWebInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public VertxWebInstrumentationModule() { super("vertx-web", "vertx-web-3.0", "vertx"); @@ -23,4 +25,9 @@ public VertxWebInstrumentationModule() { public List typeInstrumentations() { return asList(new RouteInstrumentation(), new RoutingContextInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 2ed8b96ba6634284df6be1c59d85d7f6496053a6 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:47:41 +0200 Subject: [PATCH 09/16] vertx-sql-client-4.0 --- .../vertx/v4_0/sql/PoolInstrumentation.java | 21 ++- .../sql/QueryExecutorInstrumentation.java | 125 +++++++++++------- .../sql/SqlClientBaseInstrumentation.java | 11 +- .../sql/TransactionImplInstrumentation.java | 6 +- .../VertxSqlClientInstrumentationModule.java | 5 + 5 files changed, 98 insertions(+), 70 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/PoolInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/PoolInstrumentation.java index 1a1f62f52a29..27f73b7a2d0e 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/PoolInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/PoolInstrumentation.java @@ -27,6 +27,7 @@ import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -60,23 +61,22 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class PoolAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Argument(1) SqlConnectOptions sqlConnectOptions, - @Advice.Local("otelCallDepth") CallDepth callDepth) { - callDepth = CallDepth.forClass(Pool.class); + public static CallDepth onEnter(@Advice.Argument(1) SqlConnectOptions sqlConnectOptions) { + CallDepth callDepth = CallDepth.forClass(Pool.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } // set connection options to ThreadLocal, they will be read in SqlClientBase constructor setSqlConnectOptions(sqlConnectOptions); + return callDepth; } @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit( @Advice.Return Pool pool, @Advice.Argument(1) SqlConnectOptions sqlConnectOptions, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { if (callDepth.decrementAndGet() > 0) { return; } @@ -88,14 +88,13 @@ public static void onExit( @SuppressWarnings("unused") public static class GetConnectionAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void onExit( - @Advice.This Pool pool, @Advice.Return(readOnly = false) Future future) { + public static Future onExit( + @Advice.This Pool pool, @Advice.Return Future future) { // copy connect options stored on pool to new connection SqlConnectOptions sqlConnectOptions = getPoolSqlConnectOptions(pool); - - future = attachConnectOptions(future, sqlConnectOptions); - future = wrapContext(future); + return wrapContext(attachConnectOptions(future, sqlConnectOptions)); } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java index c724abbe1192..6cab41ddc2a2 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java @@ -22,6 +22,7 @@ import io.vertx.core.impl.future.PromiseInternal; import io.vertx.sqlclient.impl.PreparedStatement; import io.vertx.sqlclient.impl.QueryExecutorUtil; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -54,71 +55,93 @@ public static void onExit(@Advice.This Object queryExecutor) { @SuppressWarnings("unused") public static class QueryAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This Object queryExecutor, - @Advice.AllArguments Object[] arguments, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelRequest") VertxSqlClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - callDepth = CallDepth.forClass(queryExecutor.getClass()); - if (callDepth.getAndIncrement() > 0) { - return; + + public static class AdviceScope { + private final CallDepth callDepth; + @Nullable private final VertxSqlClientRequest otelRequest; + @Nullable private final Context context; + @Nullable private final Scope scope; + + private AdviceScope( + CallDepth callDepth, + @Nullable VertxSqlClientRequest otelRequest, + @Nullable Context context, + @Nullable Scope scope) { + this.callDepth = callDepth; + this.otelRequest = otelRequest; + this.context = context; + this.scope = scope; } - // The parameter we need are in different positions, we are not going to have separate - // advices for all of them. The method gets the statement either as String or - // PreparedStatement, use the first argument that is either of these. PromiseInternal is - // always at the end of the argument list. - String sql = null; - PromiseInternal promiseInternal = null; - for (Object argument : arguments) { - if (sql == null) { - if (argument instanceof String) { - sql = (String) argument; - } else if (argument instanceof PreparedStatement) { - sql = ((PreparedStatement) argument).sql(); + public static AdviceScope start(Object queryExecutor, Object[] arguments) { + CallDepth callDepth = CallDepth.forClass(queryExecutor.getClass()); + if (callDepth.getAndIncrement() > 0) { + return new AdviceScope(callDepth, null, null, null); + } + + // The parameter we need are in different positions, we are not going to have separate + // advices for all of them. The method gets the statement either as String or + // PreparedStatement, use the first argument that is either of these. PromiseInternal is + // always at the end of the argument list. + String sql = null; + PromiseInternal promiseInternal = null; + for (Object argument : arguments) { + if (sql == null) { + if (argument instanceof String) { + sql = (String) argument; + } else if (argument instanceof PreparedStatement) { + sql = ((PreparedStatement) argument).sql(); + } + } else if (argument instanceof PromiseInternal) { + promiseInternal = (PromiseInternal) argument; } - } else if (argument instanceof PromiseInternal) { - promiseInternal = (PromiseInternal) argument; } - } - if (sql == null || promiseInternal == null) { - return; + if (sql == null || promiseInternal == null) { + return new AdviceScope(callDepth, null, null, null); + } + + VertxSqlClientRequest otelRequest = + new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); + Context parentContext = currentContext(); + if (!instrumenter().shouldStart(parentContext, otelRequest)) { + return new AdviceScope(callDepth, otelRequest, null, null); + } + + Context context = instrumenter().start(parentContext, otelRequest); + VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + return new AdviceScope(callDepth, otelRequest, context, context.makeCurrent()); } - otelRequest = - new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); - Context parentContext = currentContext(); - if (!instrumenter().shouldStart(parentContext, otelRequest)) { - return; + public void end(@Nullable Throwable throwable) { + if (callDepth.decrementAndGet() > 0) { + return; + } + if (scope == null || context == null || otelRequest == null) { + return; + } + + scope.close(); + if (throwable != null) { + instrumenter().end(context, otelRequest, null, throwable); + } + // span will be ended in QueryResultBuilderInstrumentation } + } - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); - VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter( + @Advice.This Object queryExecutor, @Advice.AllArguments Object[] arguments) { + return AdviceScope.start(queryExecutor, arguments); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelRequest") VertxSqlClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - if (scope == null) { - return; - } + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { - scope.close(); - if (throwable != null) { - instrumenter().end(context, otelRequest, null, throwable); + if (adviceScope != null) { + adviceScope.end(throwable); } - // span will be ended in QueryResultBuilderInstrumentation } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/SqlClientBaseInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/SqlClientBaseInstrumentation.java index af80451e7800..8ca141b75a90 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/SqlClientBaseInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/SqlClientBaseInstrumentation.java @@ -50,22 +50,21 @@ public static void onExit(@Advice.This SqlClientBase sqlClientBase) { @SuppressWarnings("unused") public static class QueryAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This SqlClientBase sqlClientBase, - @Advice.Local("otelCallDepth") CallDepth callDepth) { - callDepth = CallDepth.forClass(SqlClientBase.class); + public static CallDepth onEnter(@Advice.This SqlClientBase sqlClientBase) { + CallDepth callDepth = CallDepth.forClass(SqlClientBase.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } // set connection options to ThreadLocal, they will be read in QueryExecutor constructor SqlConnectOptions sqlConnectOptions = getSqlConnectOptions(sqlClientBase); setSqlConnectOptions(sqlConnectOptions); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Thrown Throwable throwable, @Advice.Enter CallDepth callDepth) { if (callDepth.decrementAndGet() > 0) { return; } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/TransactionImplInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/TransactionImplInstrumentation.java index 464479dd63d6..44263741cf1e 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/TransactionImplInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/TransactionImplInstrumentation.java @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.Handler; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -31,9 +32,10 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WrapHandlerAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void wrapHandler(@Advice.Return(readOnly = false) Handler handler) { - handler = HandlerWrapper.wrap(handler); + public static Handler wrapHandler(@Advice.Return Handler handler) { + return HandlerWrapper.wrap(handler); } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/VertxSqlClientInstrumentationModule.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/VertxSqlClientInstrumentationModule.java index 00523bba06cc..e6f0a5d90670 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/VertxSqlClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/VertxSqlClientInstrumentationModule.java @@ -49,4 +49,9 @@ public List typeInstrumentations() { new QueryResultBuilderInstrumentation(), new TransactionImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 809f20719b02c48c3493d8118694847c255cf747 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:58:18 +0200 Subject: [PATCH 10/16] minor code refactor --- .../v4_0/sql/QueryExecutorInstrumentation.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java index 6cab41ddc2a2..73003e5bb7e7 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java @@ -62,11 +62,12 @@ public static class AdviceScope { @Nullable private final Context context; @Nullable private final Scope scope; + private AdviceScope(CallDepth callDepth) { + this(callDepth, null, null, null); + } + private AdviceScope( - CallDepth callDepth, - @Nullable VertxSqlClientRequest otelRequest, - @Nullable Context context, - @Nullable Scope scope) { + CallDepth callDepth, VertxSqlClientRequest otelRequest, Context context, Scope scope) { this.callDepth = callDepth; this.otelRequest = otelRequest; this.context = context; @@ -76,7 +77,7 @@ private AdviceScope( public static AdviceScope start(Object queryExecutor, Object[] arguments) { CallDepth callDepth = CallDepth.forClass(queryExecutor.getClass()); if (callDepth.getAndIncrement() > 0) { - return new AdviceScope(callDepth, null, null, null); + return new AdviceScope(callDepth); } // The parameter we need are in different positions, we are not going to have separate @@ -97,7 +98,7 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) { } } if (sql == null || promiseInternal == null) { - return new AdviceScope(callDepth, null, null, null); + return new AdviceScope(callDepth); } VertxSqlClientRequest otelRequest = From 196d7c96a0ab24f8ea8510bc7447c23336ab9a9b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:59:41 +0200 Subject: [PATCH 11/16] vertx-sql-client-5.0 --- .../vertx/v5_0/sql/PoolInstrumentation.java | 19 +-- .../sql/QueryExecutorInstrumentation.java | 125 ++++++++++-------- .../sql/SqlClientBaseInstrumentation.java | 10 +- .../sql/TransactionImplInstrumentation.java | 6 +- .../VertxSqlClientInstrumentationModule.java | 5 + 5 files changed, 96 insertions(+), 69 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java index 4ff4b22b259d..7e0dd7aa883c 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java @@ -28,6 +28,7 @@ import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -61,23 +62,23 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class PoolAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Argument(1) SqlConnectOptions sqlConnectOptions, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + public static CallDepth onEnter(@Advice.Argument(1) SqlConnectOptions sqlConnectOptions) { + CallDepth callDepth = null; callDepth = CallDepth.forClass(Pool.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } // set connection options to ThreadLocal, they will be read in SqlClientBase constructor setSqlConnectOptions(sqlConnectOptions); + return callDepth; } @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit( @Advice.Return Pool pool, @Advice.Argument(1) SqlConnectOptions sqlConnectOptions, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { if (callDepth.decrementAndGet() > 0) { return; } @@ -93,14 +94,14 @@ public static void onExit( @SuppressWarnings("unused") public static class GetConnectionAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void onExit( - @Advice.This Pool pool, @Advice.Return(readOnly = false) Future future) { + public static Future onExit( + @Advice.This Pool pool, @Advice.Return Future future) { // copy connect options stored on pool to new connection SqlConnectOptions sqlConnectOptions = getPoolSqlConnectOptions(pool); - future = attachConnectOptions(future, sqlConnectOptions); - future = wrapContext(future); + return wrapContext(attachConnectOptions(future, sqlConnectOptions)); } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java index 0e78cb8e099f..d1107a95f5b1 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java @@ -22,6 +22,7 @@ import io.vertx.core.internal.PromiseInternal; import io.vertx.sqlclient.impl.QueryExecutorUtil; import io.vertx.sqlclient.internal.PreparedStatement; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -54,71 +55,89 @@ public static void onExit(@Advice.This Object queryExecutor) { @SuppressWarnings("unused") public static class QueryAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This Object queryExecutor, - @Advice.AllArguments Object[] arguments, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelRequest") VertxSqlClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - callDepth = CallDepth.forClass(queryExecutor.getClass()); - if (callDepth.getAndIncrement() > 0) { - return; + public static class AdviceScope { + private final CallDepth callDepth; + private final @Nullable VertxSqlClientRequest otelRequest; + private final @Nullable Context context; + private final @Nullable Scope scope; + + private AdviceScope(CallDepth callDepth) { + this(callDepth, null, null, null); + } + + private AdviceScope( + CallDepth callDepth, VertxSqlClientRequest otelRequest, Context context, Scope scope) { + this.callDepth = callDepth; + this.otelRequest = otelRequest; + this.context = context; + this.scope = scope; } - // The parameter we need are in different positions, we are not going to have separate - // advices for all of them. The method gets the statement either as String or - // PreparedStatement, use the first argument that is either of these. PromiseInternal is - // always at the end of the argument list. - String sql = null; - PromiseInternal promiseInternal = null; - for (Object argument : arguments) { - if (sql == null) { - if (argument instanceof String) { - sql = (String) argument; - } else if (argument instanceof PreparedStatement) { - sql = ((PreparedStatement) argument).sql(); + public static AdviceScope start(Object queryExecutor, Object[] arguments) { + CallDepth callDepth = CallDepth.forClass(queryExecutor.getClass()); + if (callDepth.getAndIncrement() > 0) { + return new AdviceScope(callDepth); + } + + // The parameter we need are in different positions, we are not going to have separate + // advices for all of them. The method gets the statement either as String or + // PreparedStatement, use the first argument that is either of these. PromiseInternal is + // always at the end of the argument list. + String sql = null; + PromiseInternal promiseInternal = null; + for (Object argument : arguments) { + if (sql == null) { + if (argument instanceof String) { + sql = (String) argument; + } else if (argument instanceof PreparedStatement) { + sql = ((PreparedStatement) argument).sql(); + } + } else if (argument instanceof PromiseInternal) { + promiseInternal = (PromiseInternal) argument; } - } else if (argument instanceof PromiseInternal) { - promiseInternal = (PromiseInternal) argument; } - } - if (sql == null || promiseInternal == null) { - return; + if (sql == null || promiseInternal == null) { + return new AdviceScope(callDepth); + } + + VertxSqlClientRequest otelRequest = + new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); + Context parentContext = currentContext(); + if (!instrumenter().shouldStart(parentContext, otelRequest)) { + return new AdviceScope(callDepth); + } + + Context context = instrumenter().start(parentContext, otelRequest); + VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + return new AdviceScope(callDepth, otelRequest, context, context.makeCurrent()); } - otelRequest = - new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); - Context parentContext = currentContext(); - if (!instrumenter().shouldStart(parentContext, otelRequest)) { - return; + public void end(Throwable throwable) { + if (callDepth.decrementAndGet() > 0) { + return; + } + if (scope == null || context == null || otelRequest == null) { + return; + } + + scope.close(); + if (throwable != null) { + instrumenter().end(context, otelRequest, null, throwable); + } + // span will be ended in QueryResultBuilderInstrumentation } + } - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); - VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter( + @Advice.This Object queryExecutor, @Advice.AllArguments Object[] arguments) { + return AdviceScope.start(queryExecutor, arguments); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelRequest") VertxSqlClientRequest otelRequest, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - if (scope == null) { - return; - } - - scope.close(); - if (throwable != null) { - instrumenter().end(context, otelRequest, null, throwable); - } - // span will be ended in QueryResultBuilderInstrumentation + @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter AdviceScope adviceScope) { + adviceScope.end(throwable); } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java index 894d1ba10e67..b051517fb465 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java @@ -50,22 +50,22 @@ public static void onExit(@Advice.This SqlClientBase sqlClientBase) { @SuppressWarnings("unused") public static class QueryAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This SqlClientBase sqlClientBase, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + public static CallDepth onEnter(@Advice.This SqlClientBase sqlClientBase) { + CallDepth callDepth = null; callDepth = CallDepth.forClass(SqlClientBase.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } // set connection options to ThreadLocal, they will be read in QueryExecutor constructor SqlConnectOptions sqlConnectOptions = getSqlConnectOptions(sqlClientBase); setSqlConnectOptions(sqlConnectOptions); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Thrown Throwable throwable, @Advice.Enter CallDepth callDepth) { if (callDepth.decrementAndGet() > 0) { return; } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/TransactionImplInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/TransactionImplInstrumentation.java index 627e58f4420f..e44755492b69 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/TransactionImplInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/TransactionImplInstrumentation.java @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.vertx.core.Completable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -31,9 +32,10 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WrapHandlerAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void wrapHandler(@Advice.Return(readOnly = false) Completable handler) { - handler = CompletableWrapper.wrap(handler); + public static Completable wrapHandler(@Advice.Return Completable handler) { + return CompletableWrapper.wrap(handler); } } } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientInstrumentationModule.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientInstrumentationModule.java index 5f02f9522e6d..25c2c7da6b4f 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientInstrumentationModule.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientInstrumentationModule.java @@ -49,4 +49,9 @@ public List typeInstrumentations() { new QueryResultBuilderInstrumentation(), new TransactionImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } From 16f555979762da7e855f296faac690446ba4473a Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:07:32 +0200 Subject: [PATCH 12/16] remove java8 bridge usage outside of advices --- .../vertx/v3_0/client/HttpRequestInstrumentation.java | 3 +-- .../vertx/v4_0/client/HttpRequestInstrumentation.java | 3 +-- .../vertx/v5_0/client/HttpRequestInstrumentation.java | 3 +-- .../v4_0/redis/RedisStandaloneConnectionInstrumentation.java | 3 +-- .../vertx/v4_0/sql/QueryExecutorInstrumentation.java | 3 +-- .../vertx/v5_0/sql/QueryExecutorInstrumentation.java | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java index d55fe9fbffbe..a8cfb91486a5 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java @@ -18,7 +18,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -103,7 +102,7 @@ public static AdviceScope startAndAttachContext(HttpClientRequest request) { return null; } - Context parentContext = Java8BytecodeBridge.currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, request)) { return null; } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java index e386d8955ed8..8a3e147a8af1 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java @@ -17,7 +17,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -99,7 +98,7 @@ private AdviceScope(Context context, Scope scope) { @Nullable public static AdviceScope startAndAttachContext(HttpClientRequest request) { - Context parentContext = Java8BytecodeBridge.currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, request)) { return null; } diff --git a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java index c174785a2689..9b04f6c8d331 100644 --- a/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx/vertx-http-client/vertx-http-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/client/HttpRequestInstrumentation.java @@ -17,7 +17,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -99,7 +98,7 @@ private AdviceScope(Context context, Scope scope) { @Nullable public static AdviceScope startAndAttachContext(HttpClientRequest request) { - Context parentContext = Java8BytecodeBridge.currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, request)) { return null; } diff --git a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java index c7b23869fe44..99b7c305228f 100644 --- a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java +++ b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java @@ -5,7 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.redis; -import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.redis.VertxRedisClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -64,7 +63,7 @@ public static AdviceScope start( VertxRedisClientRequest otelRequest = new VertxRedisClientRequest( commandName, RequestUtil.getArgs(request), redisUri, netSocket); - Context parentContext = currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, otelRequest)) { return null; } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java index 73003e5bb7e7..54b282c68e07 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java @@ -5,7 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.sql; -import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.getSqlConnectOptions; import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.sql.VertxSqlClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; @@ -103,7 +102,7 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) { VertxSqlClientRequest otelRequest = new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); - Context parentContext = currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, otelRequest)) { return new AdviceScope(callDepth, otelRequest, null, null); } diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java index d1107a95f5b1..cf7ae42882c9 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java @@ -5,7 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql; -import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.getSqlConnectOptions; import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql.VertxSqlClientSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; @@ -102,7 +101,7 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) { VertxSqlClientRequest otelRequest = new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); - Context parentContext = currentContext(); + Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, otelRequest)) { return new AdviceScope(callDepth); } From 5c3290de9fb2426f02f8c8f880d12294f88f8a44 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:12:26 +0200 Subject: [PATCH 13/16] fix style issues --- .../vertx/v5_0/sql/QueryExecutorInstrumentation.java | 6 +++--- .../vertx/v5_0/sql/SqlClientBaseInstrumentation.java | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java index cf7ae42882c9..ce532b34ad8e 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java @@ -56,9 +56,9 @@ public static void onExit(@Advice.This Object queryExecutor) { public static class QueryAdvice { public static class AdviceScope { private final CallDepth callDepth; - private final @Nullable VertxSqlClientRequest otelRequest; - private final @Nullable Context context; - private final @Nullable Scope scope; + @Nullable private final VertxSqlClientRequest otelRequest; + @Nullable private final Context context; + @Nullable private final Scope scope; private AdviceScope(CallDepth callDepth) { this(callDepth, null, null, null); diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java index b051517fb465..bb0b37e7877d 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/SqlClientBaseInstrumentation.java @@ -51,8 +51,7 @@ public static void onExit(@Advice.This SqlClientBase sqlClientBase) { public static class QueryAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static CallDepth onEnter(@Advice.This SqlClientBase sqlClientBase) { - CallDepth callDepth = null; - callDepth = CallDepth.forClass(SqlClientBase.class); + CallDepth callDepth = CallDepth.forClass(SqlClientBase.class); if (callDepth.getAndIncrement() > 0) { return callDepth; } From d67b9abda17f28d2f100341427609b3d57e84ce6 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:22:38 +0200 Subject: [PATCH 14/16] minor style fix --- .../instrumentation/vertx/v5_0/sql/PoolInstrumentation.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java index 7e0dd7aa883c..83907bed47b8 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java @@ -63,8 +63,7 @@ public void transform(TypeTransformer transformer) { public static class PoolAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static CallDepth onEnter(@Advice.Argument(1) SqlConnectOptions sqlConnectOptions) { - CallDepth callDepth = null; - callDepth = CallDepth.forClass(Pool.class); + CallDepth callDepth = CallDepth.forClass(Pool.class); if (callDepth.getAndIncrement() > 0) { return callDepth; } From e1311dba63819017f140a95c6367af876ba8b99b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:14:00 +0200 Subject: [PATCH 15/16] remove useless virtual field --- .../instrumentation/vertx/v5_0/sql/PoolInstrumentation.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java index 83907bed47b8..bb560548a3f4 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java @@ -19,7 +19,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -61,6 +60,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class PoolAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) public static CallDepth onEnter(@Advice.Argument(1) SqlConnectOptions sqlConnectOptions) { CallDepth callDepth = CallDepth.forClass(Pool.class); @@ -82,10 +82,6 @@ public static void onExit( return; } - VirtualField virtualField = - VirtualField.find(Pool.class, SqlConnectOptions.class); - virtualField.set(pool, sqlConnectOptions); - setPoolConnectOptions(pool, sqlConnectOptions); setSqlConnectOptions(null); } From b3f6622bb708acbc600c9fc02d463c42812ab20c Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:16:04 +0200 Subject: [PATCH 16/16] post-review fixes --- ...isStandaloneConnectionInstrumentation.java | 19 +++++++++++-------- .../sql/QueryExecutorInstrumentation.java | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java index 99b7c305228f..897a768504a5 100644 --- a/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java +++ b/instrumentation/vertx/vertx-redis-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/redis/RedisStandaloneConnectionInstrumentation.java @@ -42,9 +42,15 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SendAdvice { public static class AdviceScope { - public VertxRedisClientRequest otelRequest; - public Context context; - public Scope scope; + private final VertxRedisClientRequest otelRequest; + private final Context context; + private final Scope scope; + + private AdviceScope(VertxRedisClientRequest otelRequest, Context context, Scope scope) { + this.otelRequest = otelRequest; + this.context = context; + this.scope = scope; + } @Nullable public static AdviceScope start( @@ -67,11 +73,8 @@ public static AdviceScope start( if (!instrumenter().shouldStart(parentContext, otelRequest)) { return null; } - AdviceScope locals = new AdviceScope(); - locals.otelRequest = otelRequest; - locals.context = instrumenter().start(parentContext, locals.otelRequest); - locals.scope = locals.context.makeCurrent(); - return locals; + Context context = instrumenter().start(parentContext, otelRequest); + return new AdviceScope(otelRequest, context, context.makeCurrent()); } @Nullable diff --git a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java index 54b282c68e07..b7970e8cb949 100644 --- a/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java +++ b/instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java @@ -104,7 +104,7 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) { new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); Context parentContext = Context.current(); if (!instrumenter().shouldStart(parentContext, otelRequest)) { - return new AdviceScope(callDepth, otelRequest, null, null); + return new AdviceScope(callDepth, null, null, null); } Context context = instrumenter().start(parentContext, otelRequest);