Ensure that netty 4.0 instrumentation is not applied to 4.1 (#4626)

* Enusre that netty 4.0 instrumentation is not applied to 4.1

* formatting

* cross test netty instrumentation
This commit is contained in:
Lauri Tulmin 2021-11-11 18:38:56 +02:00 committed by GitHub
parent 90e2a8c325
commit d53c276b96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 7 deletions

View File

@ -25,6 +25,9 @@ dependencies {
compileOnly("io.netty:netty:3.8.0.Final")
testInstrumentation(project(":instrumentation:netty:netty-4.0:javaagent"))
testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent"))
testLibrary("io.netty:netty:3.8.0.Final")
testLibrary("com.ning:async-http-client:1.8.0")

View File

@ -5,12 +5,14 @@
package io.opentelemetry.javaagent.instrumentation.netty.v3_8;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
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 java.util.List;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public class NettyInstrumentationModule extends InstrumentationModule {
@ -18,6 +20,11 @@ public class NettyInstrumentationModule extends InstrumentationModule {
super("netty", "netty-3.8");
}
@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
return hasClassesNamed("org.jboss.netty.handler.codec.http.HttpMessage");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(

View File

@ -26,6 +26,10 @@ muzzle {
dependencies {
library("io.netty:netty-codec-http:4.0.0.Final")
implementation(project(":instrumentation:netty:netty-4-common:javaagent"))
testInstrumentation(project(":instrumentation:netty:netty-3.8:javaagent"))
testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent"))
latestDepTestLibrary("io.netty:netty-codec-http:4.0.56.Final")
}

View File

@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.netty.v4_0;
import static io.opentelemetry.javaagent.instrumentation.netty.v4_0.client.NettyClientSingletons.connectionInstrumenter;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.netty.channel.ChannelFuture;
@ -31,7 +32,9 @@ public class BootstrapInstrumentation implements TypeInstrumentation {
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
named("doConnect").and(takesArgument(0, SocketAddress.class)),
named("doConnect")
.and(takesArgument(0, SocketAddress.class))
.and(returns(named("io.netty.channel.ChannelFuture"))),
BootstrapInstrumentation.class.getName() + "$ConnectAdvice");
}

View File

@ -24,9 +24,11 @@ public class NettyInstrumentationModule extends InstrumentationModule {
@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
// Class added in 4.1.0 and not in 4.0.56 to avoid resolving this instrumentation completely
// when using 4.1.
return not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"));
return hasClassesNamed("io.netty.handler.codec.http.HttpMessage")
.and(
// Class added in 4.1.0 and not in 4.0.56 to avoid resolving this instrumentation
// completely when using 4.1.
not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders")));
}
@Override

View File

@ -28,6 +28,9 @@ dependencies {
api(project(":instrumentation:netty:netty-4.1:library"))
implementation(project(":instrumentation:netty:netty-4-common:javaagent"))
testInstrumentation(project(":instrumentation:netty:netty-3.8:javaagent"))
testInstrumentation(project(":instrumentation:netty:netty-4.0:javaagent"))
// Contains logging handler
testLibrary("io.netty:netty-handler:4.1.0.Final")
testLibrary("io.netty:netty-transport-native-epoll:4.1.0.Final:linux-x86_64")

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.tooling.muzzle;
import com.google.common.collect.EvictingQueue;
import io.opentelemetry.instrumentation.api.field.VirtualField;
import io.opentelemetry.javaagent.tooling.muzzle.references.ClassRef;
import io.opentelemetry.javaagent.tooling.muzzle.references.ClassRefBuilder;
import io.opentelemetry.javaagent.tooling.muzzle.references.Flag;
import io.opentelemetry.javaagent.tooling.muzzle.references.Flag.ManifestationFlag;
import io.opentelemetry.javaagent.tooling.muzzle.references.Flag.MinimumVisibilityFlag;
@ -435,13 +436,35 @@ final class ReferenceCollectingClassVisitor extends ClassVisitor {
for (Object arg : bootstrapMethodArguments) {
if (arg instanceof Handle) {
Handle handle = (Handle) arg;
addReference(
ClassRefBuilder classRefBuilder =
ClassRef.builder(Utils.getClassName(handle.getOwner()))
.addSource(refSourceClassName, currentLineNumber)
.addFlag(
computeMinimumClassAccess(
refSourceType, Type.getObjectType(handle.getOwner())))
.build());
refSourceType, Type.getObjectType(handle.getOwner())));
if (handle.getTag() == Opcodes.H_INVOKEVIRTUAL
|| handle.getTag() == Opcodes.H_INVOKESTATIC
|| handle.getTag() == Opcodes.H_INVOKESPECIAL
|| handle.getTag() == Opcodes.H_NEWINVOKESPECIAL
|| handle.getTag() == Opcodes.H_INVOKEINTERFACE) {
Type methodType = Type.getMethodType(handle.getDesc());
Type ownerType = Type.getObjectType(handle.getOwner());
List<Flag> methodFlags = new ArrayList<>();
methodFlags.add(
handle.getTag() == Opcodes.H_INVOKESTATIC
? OwnershipFlag.STATIC
: OwnershipFlag.NON_STATIC);
methodFlags.add(computeMinimumMethodAccess(refSourceType, ownerType));
classRefBuilder.addMethod(
new Source[] {new Source(refSourceClassName, currentLineNumber)},
methodFlags.toArray(new Flag[0]),
handle.getName(),
methodType.getReturnType(),
methodType.getArgumentTypes());
addReference(classRefBuilder.build());
}
}
}
super.visitInvokeDynamicInsn(

View File

@ -132,7 +132,26 @@ class ReferenceCollectorTest {
Map<String, ClassRef> references = collector.getReferences();
assertThat(references).containsKey("muzzle.TestClasses$MethodBodyAdvice$SomeImplementation");
assertMethod(
references.get("muzzle.TestClasses$MethodBodyAdvice$SomeImplementation"),
"someMethod",
"()V",
PROTECTED_OR_HIGHER,
OwnershipFlag.NON_STATIC);
assertThat(references).containsKey("muzzle.TestClasses$MethodBodyAdvice$B");
assertMethod(
references.get("muzzle.TestClasses$MethodBodyAdvice$B"),
"staticMethod",
"()V",
PROTECTED_OR_HIGHER,
OwnershipFlag.STATIC);
assertThat(references).containsKey("muzzle.TestClasses$MethodBodyAdvice$A");
assertMethod(
references.get("muzzle.TestClasses$MethodBodyAdvice$A"),
"<init>",
"()V",
PROTECTED_OR_HIGHER,
OwnershipFlag.NON_STATIC);
}
@Test

View File

@ -104,6 +104,7 @@ public class TestClasses {
public static MethodBodyAdvice.SomeInterface invokeDynamicMethod(
MethodBodyAdvice.SomeImplementation a) {
Runnable staticMethod = MethodBodyAdvice.B::staticMethod;
Runnable constructorMethod = MethodBodyAdvice.A::new;
return a::someMethod;
}
}