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 f36c3fdd44..dd20f8eee7 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 class HttpClientImplInstrumentation implements TypeInstrumentation { 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 1b720657ec..c65b8136d3 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 class HttpRequestImplInstrumentation implements TypeInstrumentation { @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 class HttpRequestImplInstrumentation implements TypeInstrumentation { @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 class HttpRequestImplInstrumentation implements TypeInstrumentation { @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 5590b393ec..a8cfb91486 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 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client; 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,8 +18,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; 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; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -25,7 +25,10 @@ import io.opentelemetry.javaagent.instrumentation.vertx.client.ExceptionHandlerW 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 +86,52 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @SuppressWarnings("unused") public static class EndRequestAdvice { + public static class AdviceScope { + private final Context context; + private final 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 = Context.current(); + 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) { + 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) { - - VertxRequestInfo requestInfo = - VirtualField.find(HttpClientRequest.class, VertxRequestInfo.class).get(request); - if (requestInfo == null) { - return; - } - - Context parentContext = Java8BytecodeBridge.currentContext(); - if (!instrumenter().shouldStart(parentContext, request)) { - return; - } - - context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); - - scope = context.makeCurrent(); + 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(throwable, request); } } } @@ -125,25 +139,23 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +165,23 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +191,18 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +212,16 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 ecbb82a9bf..e36e65b91c 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 static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxClientInstrumentationModule extends InstrumentationModule { 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 9153de8e39..ec46f53ba6 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; } 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 9b51318b2b..67fbb97020 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 static net.bytebuddy.matcher.ElementMatchers.takesArgument; 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 class ConnectionManagerInstrumentation implements TypeInstrumentation { @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 a2938d0e8e..794ad982a3 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 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client; 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 @@ public class HandlerWrapper implements Handler { 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 b310f747f3..636b40d7d7 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.TypeInstrumentation; 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 class HttpClientConnectionInstrumentation implements TypeInstrumentation @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 fb2b8a0895..8a3e147a8a 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 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client; 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,8 +17,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; 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; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -25,7 +24,10 @@ import io.opentelemetry.javaagent.instrumentation.vertx.client.ExceptionHandlerW 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 +87,50 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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; - if (!instrumenter().shouldStart(parentContext, request)) { - return; + private AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; } - context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); + @Nullable + public static AdviceScope startAndAttachContext(HttpClientRequest request) { + Context parentContext = Context.current(); + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } - scope = context.makeCurrent(); + 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) { + instrumenter().end(context, request, null, throwable); + } + } + } + + @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 Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + adviceScope.end(request, throwable); } } } @@ -121,25 +138,24 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +165,24 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +192,19 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 +214,16 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 c18687d452..a3b4c24e8a 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 static net.bytebuddy.matcher.ElementMatchers.not; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxClientInstrumentationModule extends InstrumentationModule { 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 1e14fa9f4f..8960551fb9 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; } 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 c1d579a8c5..9b04f6c8d3 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 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v5_0.client; 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,8 +17,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; 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; import io.opentelemetry.javaagent.instrumentation.vertx.client.Contexts; @@ -25,7 +24,10 @@ import io.opentelemetry.javaagent.instrumentation.vertx.client.ExceptionHandlerW 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 +87,47 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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; - if (!instrumenter().shouldStart(parentContext, request)) { - return; + private AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; } - context = instrumenter().start(parentContext, request); - Contexts contexts = new Contexts(parentContext, context); - VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts); + @Nullable + public static AdviceScope startAndAttachContext(HttpClientRequest request) { + Context parentContext = Context.current(); + 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()); + } - scope = context.makeCurrent(); + public void end(HttpClientRequest request, @Nullable Throwable throwable) { + scope.close(); + if (throwable != null) { + instrumenter().end(context, request, null, throwable); + } + } + } + + @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 +136,21 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { 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 +161,22 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { 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 +187,17 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { 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 +207,16 @@ public class HttpRequestInstrumentation implements TypeInstrumentation { @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 9f7d18efbf..79a6e3d472 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.TypeInstrumentation; 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 class ResourceManagerInstrumentation implements TypeInstrumentation { @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 03df65695b..737a176f26 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 static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxClientInstrumentationModule extends InstrumentationModule { 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 e7deee7947..215f28b6da 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.Context; 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 final class VertxClientSingletons { 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); } 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 24d396cad2..fd996020f1 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.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; 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 class KafkaReadStreamImplInstrumentation implements TypeInstrumentation { @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 605351f87e..7e2fd2bbb8 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 static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxKafkaInstrumentationModule extends InstrumentationModule { return asList( new KafkaReadStreamImplInstrumentation(), new KafkaConsumerRecordsImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } 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 157a7b2e36..897a768504 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; @@ -21,7 +20,9 @@ import io.vertx.redis.client.Response; 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 +41,83 @@ public class RedisStandaloneConnectionInstrumentation implements TypeInstrumenta @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 { + 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; } - String commandName = VertxRedisClientSingletons.getCommandName(request.command()); - RedisURI redisUri = VertxRedisClientSingletons.getRedisUri(connection); - if (commandName == null || redisUri == null) { - return; + @Nullable + public static AdviceScope start( + RedisStandaloneConnection connection, @Nullable Request request, NetSocket netSocket) { + + 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 = Context.current(); + if (!instrumenter().shouldStart(parentContext, otelRequest)) { + return null; + } + Context context = instrumenter().start(parentContext, otelRequest); + return new AdviceScope(otelRequest, context, context.makeCurrent()); } - 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; + } - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); + 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) { + + 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) { + + if (adviceScope != null) { + return adviceScope.end(responseFuture, throwable); } - scope.close(); - if (throwable != null) { - instrumenter().end(context, otelRequest, null, throwable); - } else { - responseFuture = - VertxRedisClientSingletons.wrapEndSpan(responseFuture, context, otelRequest); - } + 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 e3cab6a83c..9d7dc53009 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 class VertxRedisClientInstrumentationModule extends InstrumentationModule new RedisConnectionProviderInstrumentation(), new CommandImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } 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 af81b85ffb..4717f5a9d2 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.AsyncResult; 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 class AsyncResultSingleInstrumentation implements TypeInstrumentation { @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 aef5154385..b31dc3df88 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 static java.util.Collections.singletonList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxRxInstrumentationModule extends InstrumentationModule { public List typeInstrumentations() { return singletonList(new AsyncResultSingleInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } 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 1a1f62f52a..27f73b7a2d 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.Pool; 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 class PoolInstrumentation implements TypeInstrumentation { @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 class PoolInstrumentation implements TypeInstrumentation { @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 c724abbe11..b7970e8cb9 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; @@ -22,6 +21,7 @@ import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil; 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 +54,94 @@ public class QueryExecutorInstrumentation implements TypeInstrumentation { @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) { + this(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; + private AdviceScope( + CallDepth callDepth, VertxSqlClientRequest otelRequest, Context context, Scope scope) { + this.callDepth = callDepth; + this.otelRequest = otelRequest; + this.context = context; + this.scope = scope; + } + + public static AdviceScope start(Object queryExecutor, Object[] arguments) { + CallDepth callDepth = CallDepth.forClass(queryExecutor.getClass()); + if (callDepth.getAndIncrement() > 0) { + return new AdviceScope(callDepth); } - } - if (sql == null || promiseInternal == null) { - return; + + // 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; + } + } + if (sql == null || promiseInternal == null) { + return new AdviceScope(callDepth); + } + + VertxSqlClientRequest otelRequest = + new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); + Context parentContext = Context.current(); + if (!instrumenter().shouldStart(parentContext, otelRequest)) { + return new AdviceScope(callDepth, null, 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; + } - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); - VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + scope.close(); + if (throwable != null) { + instrumenter().end(context, otelRequest, null, throwable); + } + // span will be ended in QueryResultBuilderInstrumentation + } + } + + @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 af80451e78..8ca141b75a 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 class SqlClientBaseInstrumentation implements TypeInstrumentation { @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 464479dd63..44263741cf 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.TypeInstrumentation; 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 class TransactionImplInstrumentation implements TypeInstrumentation { @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 00523bba06..e6f0a5d906 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 class VertxSqlClientInstrumentationModule extends InstrumentationModule new QueryResultBuilderInstrumentation(), new TransactionImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } 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 4ff4b22b25..bb560548a3 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.takesArgument; 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; @@ -28,6 +27,7 @@ import io.vertx.sqlclient.Pool; 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,32 +60,28 @@ public class PoolInstrumentation implements TypeInstrumentation { @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; } - VirtualField virtualField = - VirtualField.find(Pool.class, SqlConnectOptions.class); - virtualField.set(pool, sqlConnectOptions); - setPoolConnectOptions(pool, sqlConnectOptions); setSqlConnectOptions(null); } @@ -93,14 +89,14 @@ public class PoolInstrumentation implements TypeInstrumentation { @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 0e78cb8e09..ce532b34ad 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; @@ -22,6 +21,7 @@ import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil; 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 +54,89 @@ public class QueryExecutorInstrumentation implements TypeInstrumentation { @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) { + this(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; + private AdviceScope( + CallDepth callDepth, VertxSqlClientRequest otelRequest, Context context, Scope scope) { + this.callDepth = callDepth; + this.otelRequest = otelRequest; + this.context = context; + this.scope = scope; + } + + public static AdviceScope start(Object queryExecutor, Object[] arguments) { + CallDepth callDepth = CallDepth.forClass(queryExecutor.getClass()); + if (callDepth.getAndIncrement() > 0) { + return new AdviceScope(callDepth); } - } - if (sql == null || promiseInternal == null) { - return; + + // 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; + } + } + if (sql == null || promiseInternal == null) { + return new AdviceScope(callDepth); + } + + VertxSqlClientRequest otelRequest = + new VertxSqlClientRequest(sql, QueryExecutorUtil.getConnectOptions(queryExecutor)); + Context parentContext = Context.current(); + 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; + } - context = instrumenter().start(parentContext, otelRequest); - scope = context.makeCurrent(); - VertxSqlClientUtil.attachRequest(promiseInternal, otelRequest, context, parentContext); + scope.close(); + if (throwable != null) { + instrumenter().end(context, otelRequest, null, throwable); + } + // span will be ended in QueryResultBuilderInstrumentation + } + } + + @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 894d1ba10e..bb0b37e787 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,21 @@ public class SqlClientBaseInstrumentation implements TypeInstrumentation { @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-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 627e58f442..e44755492b 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.TypeInstrumentation; 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 class TransactionImplInstrumentation implements TypeInstrumentation { @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 5f02f9522e..25c2c7da6b 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 class VertxSqlClientInstrumentationModule extends InstrumentationModule new QueryResultBuilderInstrumentation(), new TransactionImplInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } 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 c01649b8c7..8eb5e30166 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.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; 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 class RouteInstrumentation implements TypeInstrumentation { @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 659c2dfe50..392bd6ce67 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 static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import 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 class VertxWebInstrumentationModule extends InstrumentationModule { public List typeInstrumentations() { return asList(new RouteInstrumentation(), new RoutingContextInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } }