diff --git a/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyInstrumentationModule.java b/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyInstrumentationModule.java index edcaa162f65e..93bc79622b59 100644 --- a/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyInstrumentationModule.java +++ b/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyInstrumentationModule.java @@ -10,6 +10,7 @@ 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; /** @@ -26,7 +27,8 @@ * */ @AutoService(InstrumentationModule.class) -public class LibertyInstrumentationModule extends InstrumentationModule { +public class LibertyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public LibertyInstrumentationModule() { super("liberty", "liberty-20.0"); @@ -36,4 +38,9 @@ public LibertyInstrumentationModule() { public List typeInstrumentations() { return singletonList(new LibertyWebAppInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyWebAppInstrumentation.java b/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyWebAppInstrumentation.java index b7f118d44b16..13cae0f28e1e 100644 --- a/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyWebAppInstrumentation.java +++ b/instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyWebAppInstrumentation.java @@ -17,6 +17,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext; import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Accessor; +import javax.annotation.Nullable; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -51,18 +52,17 @@ public void transform(TypeTransformer transformer) { public static class HandleRequestAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static boolean onEnter( @Advice.Argument(value = 0) ServletRequest request, - @Advice.Argument(value = 1) ServletResponse response, - @Advice.Local("otelHandled") boolean handled) { + @Advice.Argument(value = 1) ServletResponse response) { // liberty has two handleRequest methods, skip processing when thread local context is already // set up - handled = ThreadLocalContext.get() == null; + boolean handled = ThreadLocalContext.get() == null; if (!handled || !(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { - return; + return false; } HttpServletRequest httpServletRequest = (HttpServletRequest) request; @@ -70,14 +70,15 @@ public static void onEnter( // some methods on HttpServletRequest will give a NPE // just remember the request and use it a bit later to start the span ThreadLocalContext.startRequest(httpServletRequest, (HttpServletResponse) response); + return true; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( @Advice.Argument(0) ServletRequest servletRequest, @Advice.Argument(1) ServletResponse servletResponse, - @Advice.Thrown Throwable throwable, - @Advice.Local("otelHandled") boolean handled) { + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter boolean handled) { if (!handled) { return; } diff --git a/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherInstrumentationModule.java b/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherInstrumentationModule.java index 9c38e2b99c61..de1d20cb935e 100644 --- a/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherInstrumentationModule.java +++ b/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherInstrumentationModule.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 LibertyDispatcherInstrumentationModule extends InstrumentationModule { +public class LibertyDispatcherInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public LibertyDispatcherInstrumentationModule() { super("liberty-dispatcher", "liberty-dispatcher-20.0", "liberty"); @@ -23,4 +25,9 @@ public LibertyDispatcherInstrumentationModule() { public List typeInstrumentations() { return singletonList(new LibertyDispatcherLinkInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherLinkInstrumentation.java b/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherLinkInstrumentation.java index b9c7aa06ad99..dc4b6d52b51b 100644 --- a/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherLinkInstrumentation.java +++ b/instrumentation/liberty/liberty-dispatcher-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherLinkInstrumentation.java @@ -14,9 +14,9 @@ import com.ibm.wsspi.http.channel.values.StatusCodes; 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,45 +50,63 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SendResponseAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.FieldValue("isc") HttpInboundServiceContextImpl isc, - @Advice.Local("otelRequest") LibertyRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - Context parentContext = Java8BytecodeBridge.currentContext(); - request = - new LibertyRequest( - isc.getRequest(), - isc.getLocalAddr(), - isc.getLocalPort(), - isc.getRemoteAddr(), - isc.getRemotePort()); - if (!instrumenter().shouldStart(parentContext, request)) { - return; + public static class AdviceScope { + private final LibertyRequest request; + private final Context context; + private final Scope scope; + + private AdviceScope(LibertyRequest request, Context context, Scope scope) { + this.request = request; + this.context = context; + this.scope = scope; + } + + @Nullable + public static AdviceScope start(HttpInboundServiceContextImpl isc) { + Context parentContext = Context.current(); + LibertyRequest request = + new LibertyRequest( + isc.getRequest(), + isc.getLocalAddr(), + isc.getLocalPort(), + isc.getRemoteAddr(), + isc.getRemotePort()); + if (!instrumenter().shouldStart(parentContext, request)) { + return null; + } + Context context = instrumenter().start(parentContext, request); + return new AdviceScope(request, context, context.makeCurrent()); + } + + public void end( + HttpDispatcherLink httpDispatcherLink, + @Nullable Throwable throwable, + StatusCodes statusCode, + @Nullable Exception failure) { + scope.close(); + + LibertyResponse response = new LibertyResponse(httpDispatcherLink, statusCode); + Throwable t = failure != null ? failure : throwable; + instrumenter().end(context, request, response, t); } - context = instrumenter().start(parentContext, request); - scope = context.makeCurrent(); + } + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter(@Advice.FieldValue("isc") HttpInboundServiceContextImpl isc) { + return AdviceScope.start(isc); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( @Advice.This HttpDispatcherLink httpDispatcherLink, - @Advice.Thrown Throwable throwable, + @Advice.Thrown @Nullable Throwable throwable, @Advice.Argument(value = 0) StatusCodes statusCode, @Advice.Argument(value = 2) Exception failure, - @Advice.Local("otelRequest") LibertyRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - if (scope == null) { - return; - } - scope.close(); - - LibertyResponse response = new LibertyResponse(httpDispatcherLink, statusCode); + @Advice.Enter @Nullable AdviceScope adviceScope) { - Throwable t = failure != null ? failure : throwable; - instrumenter().end(context, request, response, t); + if (adviceScope != null) { + adviceScope.end(httpDispatcherLink, throwable, statusCode, failure); + } } } }