diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/ChannelTransportInstrumentation.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/ChannelTransportInstrumentation.java index dd2f1b5ef0a4..f7490431ff92 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/ChannelTransportInstrumentation.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/ChannelTransportInstrumentation.java @@ -34,16 +34,16 @@ public void transform(TypeTransformer transformer) { public static class WriteAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void methodEnter(@Advice.Local("otelScope") Scope scope) { + public static Scope methodEnter() { Option ref = Helpers.CONTEXT_LOCAL.apply(); if (ref.isDefined()) { - scope = ref.get().makeCurrent(); + return ref.get().makeCurrent(); } + return null; } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void methodExit( - @Advice.Local("otelScope") Scope scope, @Advice.Thrown Throwable thrown) { + public static void methodExit(@Advice.Enter Scope scope, @Advice.Thrown Throwable thrown) { if (scope != null) { scope.close(); } diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java index ab8f9c9c9919..3938e762bfa4 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java @@ -8,11 +8,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.Arrays; import java.util.List; @AutoService(InstrumentationModule.class) -public class FinagleHttpInstrumentationModule extends InstrumentationModule { +public class FinagleHttpInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public FinagleHttpInstrumentationModule() { super("finagle-http", "finagle-http-23.11"); @@ -27,9 +29,17 @@ public List typeInstrumentations() { } @Override - public boolean isIndyModule() { - // injects helpers to access package-private members - return false; + public String getModuleGroup() { + // relies on netty and needs access to common netty instrumentation classes + return "netty"; + } + + @Override + public List injectedClassNames() { + // these are injected so that they can access package-private members + return Arrays.asList( + "com.twitter.finagle.ChannelTransportHelpers", + "io.netty.channel.OpenTelemetryChannelInitializerDelegate"); } @Override diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/H2StreamChannelInitInstrumentation.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/H2StreamChannelInitInstrumentation.java index 33862053cb9e..cfa7176077c7 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/H2StreamChannelInitInstrumentation.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/H2StreamChannelInitInstrumentation.java @@ -42,9 +42,10 @@ public void transform(TypeTransformer transformer) { public static class InitServerAdvice { @Advice.OnMethodExit - public static void handleExit( - @Advice.Return(readOnly = false) ChannelInitializer initializer) { - initializer = Helpers.wrapServer(initializer); + @Advice.AssignReturned.ToReturned + public static ChannelInitializer handleExit( + @Advice.Return ChannelInitializer initializer) { + return Helpers.wrapServer(initializer); } } @@ -52,9 +53,10 @@ public static void handleExit( public static class InitClientAdvice { @Advice.OnMethodExit - public static void handleExit( - @Advice.Return(readOnly = false) ChannelInitializer initializer) { - initializer = Helpers.wrapClient(initializer); + @Advice.AssignReturned.ToReturned + public static ChannelInitializer handleExit( + @Advice.Return ChannelInitializer initializer) { + return Helpers.wrapClient(initializer); } } } diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/LocalSchedulerActivationInstrumentation.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/LocalSchedulerActivationInstrumentation.java index f996916f816b..fdb66bb87853 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/LocalSchedulerActivationInstrumentation.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/LocalSchedulerActivationInstrumentation.java @@ -14,6 +14,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -35,13 +36,14 @@ public void transform(TypeTransformer transformer) { public static class WrapRunnableAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrap(@Advice.Argument(value = 0, readOnly = false) Runnable task) { + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static Runnable wrap(@Advice.Argument(value = 0) Runnable task) { if (task == null) { - return; + return null; } Context context = Java8BytecodeBridge.currentContext(); - task = ContextPropagatingRunnable.propagateContext(task, context); + return ContextPropagatingRunnable.propagateContext(task, context); } } } diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/PromiseMonitoredInstrumentation.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/PromiseMonitoredInstrumentation.java index 2cd637f4d385..af7ba98b92ac 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/PromiseMonitoredInstrumentation.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/PromiseMonitoredInstrumentation.java @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; import scala.Function1; @@ -34,13 +35,13 @@ public void transform(TypeTransformer transformer) { public static class WrapFunctionAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void wrap( - @Advice.Argument(value = 1, readOnly = false) Function1 function1) { + @Advice.AssignReturned.ToArguments(@ToArgument(1)) + public static Function1 wrap(@Advice.Argument(value = 1) Function1 function1) { if (function1 == null) { - return; + return null; } - function1 = Function1Wrapper.wrap(function1); + return Function1Wrapper.wrap(function1); } } } diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/TwitterUtilCoreInstrumentationModule.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/TwitterUtilCoreInstrumentationModule.java index 022dea36455d..1f72e97f352c 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/TwitterUtilCoreInstrumentationModule.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/TwitterUtilCoreInstrumentationModule.java @@ -10,15 +10,22 @@ 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 TwitterUtilCoreInstrumentationModule extends InstrumentationModule { +public class TwitterUtilCoreInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public TwitterUtilCoreInstrumentationModule() { super("twitter-util-core"); } + @Override + public String getModuleGroup() { + return "netty"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelInstrumentation.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelInstrumentation.java index ae09fe1377e7..6625cfbdb322 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelInstrumentation.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelInstrumentation.java @@ -56,55 +56,54 @@ public void transform(TypeTransformer transformer) { public static class ChannelConnectAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.This Channel channel, - @Advice.Argument(0) SocketAddress remoteAddress, - @Advice.Local("otelParentContext") Context parentContext, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelTimer") Timer timer) { - - parentContext = Java8BytecodeBridge.currentContext(); + public static NettyScope onEnter( + @Advice.This Channel channel, @Advice.Argument(0) SocketAddress remoteAddress) { + + Context parentContext = Java8BytecodeBridge.currentContext(); Span span = Java8BytecodeBridge.spanFromContext(parentContext); if (!span.getSpanContext().isValid()) { - return; + return null; } VirtualField virtualField = VirtualField.find(Channel.class, NettyConnectionContext.class); if (virtualField.get(channel) != null) { - return; + return null; } virtualField.set(channel, new NettyConnectionContext(parentContext)); - request = NettyConnectionRequest.connect(remoteAddress); - timer = Timer.start(); + NettyConnectionRequest request = NettyConnectionRequest.connect(remoteAddress); + Timer timer = Timer.start(); + + return new NettyScope(parentContext, request, timer); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) public static void onExit( @Advice.Return ChannelFuture channelFuture, @Advice.Thrown Throwable error, - @Advice.Local("otelParentContext") Context parentContext, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelTimer") Timer timer) { + @Advice.Enter NettyScope nettyScope) { - if (request == null) { + if (nettyScope == null) { return; } if (error != null) { - if (connectionInstrumenter().shouldStart(parentContext, request)) { + if (connectionInstrumenter() + .shouldStart(nettyScope.getParentContext(), nettyScope.getRequest())) { InstrumenterUtil.startAndEnd( connectionInstrumenter(), - parentContext, - request, + nettyScope.getParentContext(), + nettyScope.getRequest(), null, error, - timer.startTime(), - timer.now()); + nettyScope.getTimer().startTime(), + nettyScope.getTimer().now()); } } else { - channelFuture.addListener(new ConnectionListener(parentContext, request, timer)); + channelFuture.addListener( + new ConnectionListener( + nettyScope.getParentContext(), nettyScope.getRequest(), nettyScope.getTimer())); } } } diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelPipelineInstrumentation.java index 0c9b546f7cb1..f5ef00b0ba0c 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyChannelPipelineInstrumentation.java @@ -51,25 +51,25 @@ public void transform(TypeTransformer transformer) { public static class ChannelPipelineAdd2ArgsAdvice { @Advice.OnMethodEnter - public static void checkDepth( - @Advice.This ChannelPipeline pipeline, - @Advice.Argument(1) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + public static CallDepth checkDepth( + @Advice.This ChannelPipeline pipeline, @Advice.Argument(1) ChannelHandler handler) { // Pipelines are created once as a factory and then copied multiple times using the same add // methods as we are hooking. If our handler has already been added we need to remove it so we // don't end up with duplicates (this throws an exception) if (pipeline.get(handler.getClass().getName()) != null) { pipeline.remove(handler.getClass().getName()); } - callDepth = CallDepth.forClass(ChannelPipeline.class); + CallDepth callDepth = CallDepth.forClass(ChannelPipeline.class); callDepth.getAndIncrement(); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void addHandler( @Advice.This ChannelPipeline pipeline, @Advice.Argument(1) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { + if (callDepth.decrementAndGet() > 0) { return; } @@ -82,29 +82,28 @@ public static void addHandler( public static class ChannelPipelineAdd3ArgsAdvice { @Advice.OnMethodEnter - public static void checkDepth( - @Advice.This ChannelPipeline pipeline, - @Advice.Argument(2) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + public static CallDepth checkDepth( + @Advice.This ChannelPipeline pipeline, @Advice.Argument(2) ChannelHandler handler) { // Pipelines are created once as a factory and then copied multiple times using the same add // methods as we are hooking. If our handler has already been added we need to remove it so we // don't end up with duplicates (this throws an exception) if (pipeline.get(handler.getClass().getName()) != null) { pipeline.remove(handler.getClass().getName()); } - callDepth = CallDepth.forClass(ChannelPipeline.class); + CallDepth callDepth = CallDepth.forClass(ChannelPipeline.class); callDepth.getAndIncrement(); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void addHandler( @Advice.This ChannelPipeline pipeline, @Advice.Argument(2) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { + if (callDepth.decrementAndGet() > 0) { return; } - ChannelPipelineUtil.wrapHandler(pipeline, handler); } } diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java index 54b65990b13f..a6cb34099421 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-3.8"); } @@ -25,6 +27,11 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.jboss.netty.handler.codec.http.HttpMessage"); } + @Override + public String getModuleGroup() { + return "netty"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyScope.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyScope.java new file mode 100644 index 000000000000..56d4a34ecef7 --- /dev/null +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyScope.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.netty.v3_8; + +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.netty.common.internal.NettyConnectionRequest; +import io.opentelemetry.instrumentation.netty.common.internal.Timer; + +/** Container used to carry state between enter and exit advices */ +public class NettyScope { + + private final Context parentContext; + private final NettyConnectionRequest request; + private final Timer timer; + + public NettyScope(Context parentContext, NettyConnectionRequest request, Timer timer) { + this.parentContext = parentContext; + this.request = request; + this.timer = timer; + } + + public Context getParentContext() { + return parentContext; + } + + public NettyConnectionRequest getRequest() { + return request; + } + + public Timer getTimer() { + return timer; + } +} diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/AbstractNettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/AbstractNettyChannelPipelineInstrumentation.java index 0abc18d2aa31..155927b915fb 100644 --- a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/AbstractNettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/AbstractNettyChannelPipelineInstrumentation.java @@ -22,6 +22,7 @@ import java.util.Iterator; import java.util.Map; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -154,11 +155,13 @@ public static void removeHandler( public static class RemoveLastAdvice { @Advice.OnMethodExit(suppress = Throwable.class) - public static void removeHandler( - @Advice.This ChannelPipeline pipeline, - @Advice.Return(readOnly = false) ChannelHandler handler) { + @Advice.AssignReturned.ToReturned + public static ChannelHandler removeHandler( + @Advice.This ChannelPipeline pipeline, @Advice.Return ChannelHandler returnHandler) { VirtualField virtualField = VirtualField.find(ChannelHandler.class, ChannelHandler.class); + // TODO remove this extra variable when migrating to "indy only" instrumentation. + ChannelHandler handler = returnHandler; ChannelHandler ourHandler = virtualField.get(handler); if (ourHandler != null) { // Context is null when our handler has already been removed. This happens when calling @@ -176,6 +179,7 @@ public static void removeHandler( handler = pipeline.removeLast(); } } + return handler; } } @@ -183,9 +187,14 @@ public static void removeHandler( public static class AddAfterAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void addAfterHandler( - @Advice.This ChannelPipeline pipeline, - @Advice.Argument(value = 1, readOnly = false) String name) { + @Advice.AssignReturned.ToArguments(@ToArgument(1)) + public static String addAfterHandler( + @Advice.This ChannelPipeline pipeline, @Advice.Argument(value = 1) String nameArg) { + // TODO remove this extra variable when migrating to "indy only" instrumentation. + // using an intermediate variable is required to keep the advice work with "inlined" and + // "indy" this is probably a minor side-effect of using @Advice.AssignReturned.ToArguments + // with and inlined advice. + String name = nameArg; ChannelHandler handler = pipeline.get(name); if (handler != null) { VirtualField virtualField = @@ -195,6 +204,7 @@ public static void addAfterHandler( name = ourHandler.getClass().getName(); } } + return name; } } diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyFutureInstrumentation.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyFutureInstrumentation.java index 49a0b86756bf..697cca48f05e 100644 --- a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyFutureInstrumentation.java +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyFutureInstrumentation.java @@ -19,6 +19,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -58,22 +59,30 @@ public void transform(TypeTransformer transformer) { public static class AddListenerAdvice { @Advice.OnMethodEnter - public static void wrapListener( - @Advice.Argument(value = 0, readOnly = false) - GenericFutureListener> listener) { + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static GenericFutureListener> wrapListener( + @Advice.Argument(value = 0) GenericFutureListener> listenerArg) { + + // TODO remove this extra variable when migrating to "indy only" instrumentation. + GenericFutureListener> listener = listenerArg; if (FutureListenerWrappers.shouldWrap(listener)) { listener = FutureListenerWrappers.wrap(Java8BytecodeBridge.currentContext(), listener); } + return listener; } } @SuppressWarnings("unused") public static class AddListenersAdvice { + // here the AsScalar allows to assign the value of the returned array to the argument value, + // otherwise it's considered to be an Object[] that contains the arguments/return value/thrown + // exception assignments that bytebuddy has to do after the advice is invoked. @Advice.OnMethodEnter - public static void wrapListener( - @Advice.Argument(value = 0, readOnly = false) - GenericFutureListener>[] listeners) { + @Advice.AssignReturned.AsScalar + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static Object[] wrapListener( + @Advice.Argument(value = 0) GenericFutureListener>[] listeners) { Context context = Java8BytecodeBridge.currentContext(); @SuppressWarnings({"unchecked", "rawtypes"}) @@ -86,7 +95,7 @@ public static void wrapListener( wrappedListeners[i] = listeners[i]; } } - listeners = wrappedListeners; + return wrappedListeners; } } @@ -94,20 +103,24 @@ public static void wrapListener( public static class RemoveListenerAdvice { @Advice.OnMethodEnter - public static void wrapListener( - @Advice.Argument(value = 0, readOnly = false) - GenericFutureListener> listener) { - listener = FutureListenerWrappers.getWrapper(listener); + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static GenericFutureListener> wrapListener( + @Advice.Argument(value = 0) GenericFutureListener> listener) { + return FutureListenerWrappers.getWrapper(listener); } } @SuppressWarnings("unused") public static class RemoveListenersAdvice { + // here the AsScalar allows to assign the value of the returned array to the argument value, + // otherwise it's considered to be an Object[] that contains the arguments/return value/thrown + // exception assignments that bytebuddy has to do after the advice is invoked. @Advice.OnMethodEnter - public static void wrapListener( - @Advice.Argument(value = 0, readOnly = false) - GenericFutureListener>[] listeners) { + @Advice.AssignReturned.AsScalar + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static Object[] wrapListener( + @Advice.Argument(value = 0) GenericFutureListener>[] listeners) { @SuppressWarnings({"unchecked", "rawtypes"}) GenericFutureListener>[] wrappedListeners = @@ -115,7 +128,7 @@ public static void wrapListener( for (int i = 0; i < listeners.length; ++i) { wrappedListeners[i] = FutureListenerWrappers.getWrapper(listeners[i]); } - listeners = wrappedListeners; + return wrappedListeners; } } } diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyScope.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyScope.java new file mode 100644 index 000000000000..94b7f997b24f --- /dev/null +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/NettyScope.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.netty.v4.common; + +import io.netty.channel.ChannelPromise; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.netty.common.internal.NettyConnectionRequest; +import io.opentelemetry.instrumentation.netty.v4.common.internal.client.ConnectionCompleteListener; +import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyConnectionInstrumenter; + +/** Container used to carry state between enter and exit advices */ +public class NettyScope { + + private final Context context; + private final NettyConnectionRequest request; + private final Scope scope; + + private NettyScope(Context context, NettyConnectionRequest request, Scope scope) { + this.context = context; + this.request = request; + this.scope = scope; + } + + public static NettyScope startNew( + NettyConnectionInstrumenter instrumenter, + Context parentContext, + NettyConnectionRequest request) { + Context context = instrumenter.start(parentContext, request); + return new NettyScope(context, request, context.makeCurrent()); + } + + public static void end( + NettyScope nettyScope, + NettyConnectionInstrumenter instrumenter, + ChannelPromise channelPromise, + Throwable throwable) { + + if (nettyScope == null) { + return; + } + + nettyScope.scope.close(); + + if (throwable != null) { + instrumenter.end(nettyScope.context, nettyScope.request, null, throwable); + } else { + channelPromise.addListener( + new ConnectionCompleteListener(instrumenter, nettyScope.context, nettyScope.request)); + } + } +} diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/BootstrapInstrumentation.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/BootstrapInstrumentation.java index e7260ed353be..37dcd6cfcd0c 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/BootstrapInstrumentation.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/BootstrapInstrumentation.java @@ -11,12 +11,11 @@ import io.netty.channel.ChannelPromise; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.netty.common.internal.NettyConnectionRequest; -import io.opentelemetry.instrumentation.netty.v4.common.internal.client.ConnectionCompleteListener; 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.netty.v4.common.NettyScope; import java.net.SocketAddress; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -40,42 +39,24 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class ConnectAdvice { @Advice.OnMethodEnter - public static void startConnect( - @Advice.Argument(2) SocketAddress remoteAddress, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelScope") Scope scope) { + public static NettyScope startConnect(@Advice.Argument(2) SocketAddress remoteAddress) { Context parentContext = Java8BytecodeBridge.currentContext(); - request = NettyConnectionRequest.connect(remoteAddress); + NettyConnectionRequest request = NettyConnectionRequest.connect(remoteAddress); if (!connectionInstrumenter().shouldStart(parentContext, request)) { - return; + return null; } - - context = connectionInstrumenter().start(parentContext, request); - scope = context.makeCurrent(); + return NettyScope.startNew(connectionInstrumenter(), parentContext, request); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endConnect( @Advice.Thrown Throwable throwable, @Advice.Argument(4) ChannelPromise channelPromise, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelScope") Scope scope) { - - if (scope == null) { - return; - } - scope.close(); + @Advice.Enter NettyScope enterScope) { - if (throwable != null) { - connectionInstrumenter().end(context, request, null, throwable); - } else { - channelPromise.addListener( - new ConnectionCompleteListener(connectionInstrumenter(), context, request)); - } + NettyScope.end(enterScope, connectionInstrumenter(), channelPromise, throwable); } } } diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java index d913369e31fd..0db21d84da39 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java @@ -54,16 +54,18 @@ public void transform(TypeTransformer transformer) { public static class ChannelPipelineAddAdvice { @Advice.OnMethodEnter - public static void trackCallDepth(@Advice.Local("otelCallDepth") CallDepth callDepth) { - callDepth = CallDepth.forClass(ChannelPipeline.class); + public static CallDepth trackCallDepth() { + CallDepth callDepth = CallDepth.forClass(ChannelPipeline.class); callDepth.getAndIncrement(); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void addHandler( @Advice.This ChannelPipeline pipeline, @Advice.Argument(2) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { + if (callDepth.decrementAndGet() > 0) { return; } diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java index 1d2151795892..a20246a5d1e3 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java @@ -12,12 +12,14 @@ 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 io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.0"); } @@ -31,6 +33,11 @@ public ElementMatcher.Junction classLoaderMatcher() { not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"))); } + @Override + public String getModuleGroup() { + return "netty"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/BootstrapInstrumentation.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/BootstrapInstrumentation.java index aa91de4d1bb3..2801c847eb5a 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/BootstrapInstrumentation.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/BootstrapInstrumentation.java @@ -16,14 +16,14 @@ import io.netty.resolver.AddressResolverGroup; import io.netty.resolver.DefaultAddressResolverGroup; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.netty.common.internal.NettyConnectionRequest; -import io.opentelemetry.instrumentation.netty.v4.common.internal.client.ConnectionCompleteListener; 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.netty.v4.common.NettyScope; import java.net.SocketAddress; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -66,50 +66,34 @@ public static void onExit(@Advice.This Bootstrap bootstrap) { public static class SetResolverAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Argument(value = 0, readOnly = false) AddressResolverGroup resolver) { - resolver = InstrumentedAddressResolverGroup.wrap(connectionInstrumenter(), resolver); + @Advice.AssignReturned.ToArguments(@ToArgument(0)) + public static AddressResolverGroup onEnter( + @Advice.Argument(value = 0) AddressResolverGroup resolver) { + return InstrumentedAddressResolverGroup.wrap(connectionInstrumenter(), resolver); } } @SuppressWarnings("unused") public static class ConnectAdvice { @Advice.OnMethodEnter - public static void startConnect( - @Advice.Argument(0) SocketAddress remoteAddress, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelScope") Scope scope) { + public static NettyScope startConnect(@Advice.Argument(0) SocketAddress remoteAddress) { Context parentContext = Java8BytecodeBridge.currentContext(); - request = NettyConnectionRequest.connect(remoteAddress); + NettyConnectionRequest request = NettyConnectionRequest.connect(remoteAddress); if (!connectionInstrumenter().shouldStart(parentContext, request)) { - return; + return null; } - context = connectionInstrumenter().start(parentContext, request); - scope = context.makeCurrent(); + return NettyScope.startNew(connectionInstrumenter(), parentContext, request); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endConnect( @Advice.Thrown Throwable throwable, @Advice.Argument(2) ChannelPromise channelPromise, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelRequest") NettyConnectionRequest request, - @Advice.Local("otelScope") Scope scope) { + @Advice.Enter NettyScope enterScope) { - if (scope == null) { - return; - } - scope.close(); - - if (throwable != null) { - connectionInstrumenter().end(context, request, null, throwable); - } else { - channelPromise.addListener( - new ConnectionCompleteListener(connectionInstrumenter(), context, request)); - } + NettyScope.end(enterScope, connectionInstrumenter(), channelPromise, throwable); } } } diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java index 75e45800d591..9bdb10ef14c0 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java @@ -52,9 +52,7 @@ public void transform(TypeTransformer transformer) { public static class ChannelPipelineAddAdvice { @Advice.OnMethodEnter - public static void trackCallDepth( - @Advice.Argument(2) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + public static CallDepth trackCallDepth(@Advice.Argument(2) ChannelHandler handler) { // Previously we used one unique call depth tracker for all handlers, using // ChannelPipeline.class as a key. // The problem with this approach is that it does not work with netty's @@ -64,8 +62,9 @@ public static void trackCallDepth( // Using the specific handler key instead of the generic ChannelPipeline.class will help us // both to handle such cases and avoid adding our additional handlers in case of internal // calls of `addLast` to other method overloads with a compatible signature. - callDepth = CallDepth.forClass(handler.getClass()); + CallDepth callDepth = CallDepth.forClass(handler.getClass()); callDepth.getAndIncrement(); + return callDepth; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) @@ -73,7 +72,8 @@ public static void addHandler( @Advice.This ChannelPipeline pipeline, @Advice.Argument(1) String handlerName, @Advice.Argument(2) ChannelHandler handler, - @Advice.Local("otelCallDepth") CallDepth callDepth) { + @Advice.Enter CallDepth callDepth) { + if (callDepth.decrementAndGet() > 0) { return; } diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java index 6f5f5a28038b..9d9c71505726 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java @@ -11,12 +11,14 @@ 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 io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.1"); } @@ -29,10 +31,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // netty instrumentation classes are used in other instrumentations which causes class cast - // exceptions - return false; + public String getModuleGroup() { + return "netty"; } @Override diff --git a/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/RatpackInstrumentationModule.java b/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/RatpackInstrumentationModule.java index c0530aedfb79..ea02d096b3db 100644 --- a/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/RatpackInstrumentationModule.java +++ b/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/RatpackInstrumentationModule.java @@ -10,22 +10,20 @@ 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 RatpackInstrumentationModule extends InstrumentationModule { +public class RatpackInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public RatpackInstrumentationModule() { super("ratpack", "ratpack-1.4"); } @Override - public boolean isIndyModule() { - // java.lang.ClassCastException: class - // io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.AutoValue_ServerContext - // cannot be cast to class - // io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.ServerContext - // (io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.AutoValue_ServerContext is in unnamed module of loader 'app'; io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.ServerContext is in unnamed module of loader io.opentelemetry.javaagent.tooling.instrumentation.indy.InstrumentationModuleClassLoader @7f088b5c) - return false; + public String getModuleGroup() { + // relies on netty + return "netty"; } @Override diff --git a/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/gateway/v2_0/GatewayInstrumentationModule.java b/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/gateway/v2_0/GatewayInstrumentationModule.java index c5b719af8f14..a47ca107b88f 100644 --- a/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/gateway/v2_0/GatewayInstrumentationModule.java +++ b/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/gateway/v2_0/GatewayInstrumentationModule.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 GatewayInstrumentationModule extends InstrumentationModule { +public class GatewayInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public GatewayInstrumentationModule() { super("spring-cloud-gateway"); @@ -24,6 +26,12 @@ public List typeInstrumentations() { return asList(new HandlerAdapterInstrumentation()); } + @Override + public String getModuleGroup() { + // relies on netty + return "netty"; + } + @Override public int order() { // Later than Spring Webflux. diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java index 047603fc19d4..8abd3d0a954e 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java @@ -8,20 +8,22 @@ 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.Arrays; import java.util.List; @AutoService(InstrumentationModule.class) -public class ReactorNettyInstrumentationModule extends InstrumentationModule { +public class ReactorNettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ReactorNettyInstrumentationModule() { super("reactor-netty", "reactor-netty-server"); } @Override - public boolean isIndyModule() { - // uses classes from netty instrumentation that are now in a different class loader - return false; + public String getModuleGroup() { + // relies on netty + return "netty"; } @Override