diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraExceptionManagerInstrumentation.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraExceptionManagerInstrumentation.java index 1720e3356385..785c627af7ab 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraExceptionManagerInstrumentation.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraExceptionManagerInstrumentation.java @@ -5,13 +5,13 @@ package io.opentelemetry.javaagent.instrumentation.finatra; +import static io.opentelemetry.javaagent.instrumentation.finatra.FinatraSingletons.THROWABLE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import com.twitter.finagle.http.Response; -import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import net.bytebuddy.asm.Advice; @@ -45,9 +45,7 @@ public static void handleException( return; } - VirtualField virtualField = - VirtualField.find(Response.class, Throwable.class); - virtualField.set(response, throwable); + THROWABLE.set(response, throwable); } } } diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java index f604a53a2fd9..6f8febef19db 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class FinatraInstrumentationModule extends InstrumentationModule { +public class FinatraInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public FinatraInstrumentationModule() { super("finatra", "finatra-2.9"); } @@ -25,4 +27,9 @@ public List typeInstrumentations() { new FinatraRouteBuilderInstrumentation(), new FinatraExceptionManagerInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraResponseListener.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraResponseListener.java index 505726495b1d..1d2d6e4a3ed5 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraResponseListener.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraResponseListener.java @@ -5,18 +5,15 @@ package io.opentelemetry.javaagent.instrumentation.finatra; +import static io.opentelemetry.javaagent.instrumentation.finatra.FinatraSingletons.THROWABLE; import static io.opentelemetry.javaagent.instrumentation.finatra.FinatraSingletons.instrumenter; import com.twitter.finagle.http.Response; import com.twitter.util.FutureEventListener; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.util.VirtualField; public final class FinatraResponseListener implements FutureEventListener { - private static final VirtualField responseThrowableField = - VirtualField.find(Response.class, Throwable.class); - private final Context context; private final FinatraRequest request; @@ -27,7 +24,7 @@ public FinatraResponseListener(Context context, FinatraRequest request) { @Override public void onSuccess(Response response) { - Throwable throwable = responseThrowableField.get(response); + Throwable throwable = THROWABLE.get(response); instrumenter().end(context, request, null, throwable); } diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraRouteInstrumentation.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraRouteInstrumentation.java index 4506bb69405d..f80afb7cb5f8 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraRouteInstrumentation.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraRouteInstrumentation.java @@ -20,9 +20,9 @@ import com.twitter.util.Future; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -50,50 +50,66 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class HandleMatchAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void nameSpan( - @Advice.This Route route, - @Advice.FieldValue("routeInfo") RouteInfo routeInfo, - @Advice.FieldValue("clazz") Class controllerClass, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Local("otelRequest") FinatraRequest request) { - Context parentContext = Java8BytecodeBridge.currentContext(); - updateServerSpanName(parentContext, routeInfo); - - Class callbackClass = getCallbackClass(route); - // We expect callback to be an inner class of the controller class. If it is not we are not - // going to record it at all. - if (callbackClass != null) { - request = FinatraRequest.create(controllerClass, callbackClass, "apply"); - } else { - request = FinatraRequest.create(controllerClass); + public static class AdviceScope { + private final FinatraRequest request; + private final Context context; + private final Scope scope; + + private AdviceScope(FinatraRequest request, Context context, Scope scope) { + this.request = request; + this.context = context; + this.scope = scope; } - if (!instrumenter().shouldStart(parentContext, request)) { - return; + @Nullable + public static AdviceScope start(Route route, RouteInfo routeInfo, Class controllerClass) { + + Context parentContext = Context.current(); + updateServerSpanName(parentContext, routeInfo); + + Class callbackClass = getCallbackClass(route); + // We expect callback to be an inner class of the controller class. If it is not we are not + // going to record it at all. + FinatraRequest request; + if (callbackClass != null) { + request = FinatraRequest.create(controllerClass, callbackClass, "apply"); + } else { + request = FinatraRequest.create(controllerClass); + } + + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } + Context context = instrumenter().start(parentContext, request); + return new AdviceScope(request, context, context.makeCurrent()); } - context = instrumenter().start(parentContext, request); - scope = context.makeCurrent(); + public void end( + @Nullable Throwable throwable, @Nullable Some> responseOption) { + scope.close(); + if (throwable != null || responseOption == null) { + instrumenter().end(context, request, null, throwable); + } else { + responseOption.get().addEventListener(new FinatraResponseListener(context, request)); + } + } + } + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope nameSpan( + @Advice.This Route route, + @Advice.FieldValue("routeInfo") RouteInfo routeInfo, + @Advice.FieldValue("clazz") Class controllerClass) { + return AdviceScope.start(route, routeInfo, controllerClass); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void setupCallback( - @Advice.Thrown Throwable throwable, - @Advice.Return Some> responseOption, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Local("otelRequest") FinatraRequest request) { - if (scope == null) { - return; - } - scope.close(); - - if (throwable != null) { - instrumenter().end(context, request, null, throwable); - } else { - responseOption.get().addEventListener(new FinatraResponseListener(context, request)); + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Return @Nullable Some> responseOption, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + adviceScope.end(throwable, responseOption); } } } diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraSingletons.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraSingletons.java index bbedf3944247..5572555b0ff4 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraSingletons.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraSingletons.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.finatra; +import com.twitter.finagle.http.Response; import com.twitter.finatra.http.contexts.RouteInfo; import com.twitter.finatra.http.internal.routing.Route; import io.opentelemetry.api.GlobalOpenTelemetry; @@ -18,6 +19,9 @@ public final class FinatraSingletons { + public static final VirtualField THROWABLE = + VirtualField.find(Response.class, Throwable.class); + private static final Instrumenter INSTRUMENTER; static {