From 44905cb2d620bd7b2d02e16c1ba074b9d1c82606 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 05:32:10 -0400 Subject: [PATCH 01/15] Implement netty 3.9 instrumentation --- .../netty-3.9/netty-3.9.gradle | 51 +++++ .../ChannelFutureListenerInstrumentation.java | 116 ++++++++++ .../instrumentation/netty39/ChannelState.java | 39 ++++ .../netty39/NettyChannelInstrumentation.java | 84 ++++++++ .../NettyChannelPipelineInstrumentation.java | 204 ++++++++++++++++++ .../HttpClientRequestTracingHandler.java | 81 +++++++ .../HttpClientResponseTracingHandler.java | 54 +++++ .../client/HttpClientTracingHandler.java | 17 ++ .../client/NettyHttpClientDecorator.java | 45 ++++ .../client/NettyResponseInjectAdapter.java | 14 ++ .../HttpServerRequestTracingHandler.java | 71 ++++++ .../HttpServerResponseTracingHandler.java | 49 +++++ .../server/HttpServerTracingHandler.java | 17 ++ .../server/NettyHttpServerDecorator.java | 67 ++++++ .../server/NettyRequestExtractAdapter.java | 19 ++ .../util/CombinedSimpleChannelHandler.java | 152 +++++++++++++ .../src/test/groovy/Netty39ClientTest.groovy | 103 +++++++++ .../src/test/groovy/Netty39ServerTest.groovy | 111 ++++++++++ .../NettyServerTestInstrumentation.java | 21 ++ 19 files changed, 1315 insertions(+) create mode 100644 dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy create mode 100644 dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java diff --git a/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle b/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle new file mode 100644 index 0000000000..d36edb443a --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle @@ -0,0 +1,51 @@ +// Set properties before any plugins get loaded +ext { + minJavaVersionForTests = JavaVersion.VERSION_1_8 + maxJavaVersionForTests = JavaVersion.VERSION_1_8 +} + +apply from: "${rootDir}/gradle/java.gradle" + +muzzle { + pass { + group = "io.netty" + module = "netty" + versions = "[3.9.0.Final,4)" + assertInverse = true + } + fail { + group = "io.netty" + module = "netty-all" + versions = "[,]" + } +} + +apply plugin: 'org.unbroken-dome.test-sets' + +testSets { + latestDepTest { + dirName = 'test' + } +} + +dependencies { + compileOnly group: 'io.netty', name: 'netty', version: '3.9.0.Final' + + testCompile group: 'io.netty', name: 'netty', version: '3.9.0.Final' + testCompile group: 'com.ning', name: 'async-http-client', version: '1.8.0' + + latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.9.9.Final' + latestDepTestCompile group: 'com.ning', name: 'async-http-client', version: '1.8.+' +} + +// We need to force the dependency to the earliest supported version because other libraries declare newer versions. +configurations.testCompile { + resolutionStrategy { + eachDependency { DependencyResolveDetails details -> + //specifying a fixed version for all libraries with io.netty' group + if (details.requested.group == 'io.netty') { + details.useVersion "3.9.0.Final" + } + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java new file mode 100644 index 0000000000..85b9977046 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java @@ -0,0 +1,116 @@ +package datadog.trace.instrumentation.netty39; + +import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; +import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Tags; +import datadog.trace.context.TraceScope; +import datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator; +import java.util.Collections; +import java.util.Map; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; + +@AutoService(Instrumenter.class) +public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { + + public ChannelFutureListenerInstrumentation() { + super( + NettyChannelPipelineInstrumentation.INSTRUMENTATION_NAME, + NettyChannelPipelineInstrumentation.ADDITIONAL_INSTRUMENTATION_NAMES); + } + + @Override + public ElementMatcher classLoaderMatcher() { + // Optimization for expensive typeMatcher. + return hasClassesNamed("org.jboss.netty.channel.ChannelFutureListener"); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named("org.jboss.netty.channel.ChannelFutureListener")); + } + + @Override + public String[] helperClassNames() { + return new String[] { + packageName + ".ChannelState", + packageName + ".server.NettyHttpServerDecorator", + packageName + ".server.NettyRequestExtractAdapter" + }; + } + + @Override + public Map, String> transformers() { + return singletonMap( + isMethod() + .and(named("operationComplete")) + .and(takesArgument(0, named("org.jboss.netty.channel.ChannelFuture"))), + ChannelFutureListenerInstrumentation.class.getName() + "$OperationCompleteAdvice"); + } + + @Override + public Map contextStore() { + return Collections.singletonMap( + "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + } + + public static class OperationCompleteAdvice { + @Advice.OnMethodEnter + public static TraceScope activateScope(@Advice.Argument(0) final ChannelFuture future) { + /* + Idea here is: + - To return scope only if we have captured it. + - To capture scope only in case of error. + */ + final Throwable cause = future.getCause(); + if (cause == null) { + return null; + } + + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelState.class); + + final TraceScope.Continuation continuation = + contextStore + .putIfAbsent(future.getChannel(), ChannelState.Factory.INSTANCE) + .getConnectionContinuationAndRemove(); + if (continuation == null) { + return null; + } + final TraceScope parentScope = continuation.activate(); + + final AgentSpan errorSpan = startSpan("netty.connect").setTag(Tags.COMPONENT, "netty"); + try (final AgentScope scope = activateSpan(errorSpan, false)) { + NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause); + NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan); + errorSpan.finish(); + } + + return parentScope; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void deactivateScope(@Advice.Enter final TraceScope scope) { + if (scope != null) { + scope.close(); + } + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java new file mode 100644 index 0000000000..3c19f4ebb6 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java @@ -0,0 +1,39 @@ +package datadog.trace.instrumentation.netty39; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.context.TraceScope; +import lombok.Data; + +@Data +public class ChannelState { + public static class Factory implements ContextStore.Factory { + public static final Factory INSTANCE = new Factory(); + + @Override + public ChannelState create() { + return new ChannelState(); + } + } + + TraceScope.Continuation connectionContinuation; + AgentSpan serverSpan; + AgentSpan clientSpan; + AgentSpan clientParentSpan; + + public boolean compareAndSet( + final TraceScope.Continuation compareTo, final TraceScope.Continuation setTo) { + if (connectionContinuation == compareTo) { + connectionContinuation = setTo; + return true; + } else { + return false; + } + } + + public TraceScope.Continuation getConnectionContinuationAndRemove() { + final TraceScope.Continuation current = connectionContinuation; + connectionContinuation = null; + return current; + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java new file mode 100644 index 0000000000..e3f51ea34d --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java @@ -0,0 +1,84 @@ +package datadog.trace.instrumentation.netty39; + +import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; +import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope; +import static datadog.trace.instrumentation.netty39.NettyChannelPipelineInstrumentation.ADDITIONAL_INSTRUMENTATION_NAMES; +import static datadog.trace.instrumentation.netty39.NettyChannelPipelineInstrumentation.INSTRUMENTATION_NAME; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.returns; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.context.TraceScope; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.jboss.netty.channel.Channel; + +@AutoService(Instrumenter.class) +public class NettyChannelInstrumentation extends Instrumenter.Default { + public NettyChannelInstrumentation() { + super(INSTRUMENTATION_NAME, ADDITIONAL_INSTRUMENTATION_NAMES); + } + + @Override + public ElementMatcher classLoaderMatcher() { + // Optimization for expensive typeMatcher. + return hasClassesNamed("org.jboss.netty.channel.Channel"); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named("org.jboss.netty.channel.Channel")); + } + + @Override + public String[] helperClassNames() { + return new String[] {packageName + ".ChannelState"}; + } + + @Override + public Map, String> transformers() { + final Map, String> transformers = new HashMap<>(); + transformers.put( + isMethod() + .and(named("connect")) + .and(returns(named("org.jboss.netty.channel.ChannelFuture"))), + NettyChannelInstrumentation.class.getName() + "$ChannelConnectAdvice"); + return transformers; + } + + @Override + public Map contextStore() { + return Collections.singletonMap( + "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + } + + public static class ChannelConnectAdvice { + @Advice.OnMethodEnter + public static void addConnectContinuation(@Advice.This final Channel channel) { + final TraceScope scope = activeScope(); + if (scope != null) { + final TraceScope.Continuation continuation = scope.capture(); + if (continuation != null) { + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelState.class); + + if (!contextStore + .putIfAbsent(channel, ChannelState.Factory.INSTANCE) + .compareAndSet(null, continuation)) { + continuation.close(); + } + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java new file mode 100644 index 0000000000..e78313d40a --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java @@ -0,0 +1,204 @@ +package datadog.trace.instrumentation.netty39; + +import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; +import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.bootstrap.CallDepthThreadLocalMap; +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.instrumentation.netty39.client.HttpClientRequestTracingHandler; +import datadog.trace.instrumentation.netty39.client.HttpClientResponseTracingHandler; +import datadog.trace.instrumentation.netty39.client.HttpClientTracingHandler; +import datadog.trace.instrumentation.netty39.server.HttpServerRequestTracingHandler; +import datadog.trace.instrumentation.netty39.server.HttpServerResponseTracingHandler; +import datadog.trace.instrumentation.netty39.server.HttpServerTracingHandler; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandler; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.http.HttpClientCodec; +import org.jboss.netty.handler.codec.http.HttpRequestDecoder; +import org.jboss.netty.handler.codec.http.HttpRequestEncoder; +import org.jboss.netty.handler.codec.http.HttpResponseDecoder; +import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import org.jboss.netty.handler.codec.http.HttpServerCodec; + +@AutoService(Instrumenter.class) +public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { + + static final String INSTRUMENTATION_NAME = "netty"; + static final String[] ADDITIONAL_INSTRUMENTATION_NAMES = {"netty-3.9"}; + + public NettyChannelPipelineInstrumentation() { + super(INSTRUMENTATION_NAME, ADDITIONAL_INSTRUMENTATION_NAMES); + } + + @Override + public ElementMatcher classLoaderMatcher() { + // Optimization for expensive typeMatcher. + return hasClassesNamed("org.jboss.netty.channel.ChannelPipeline"); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named("org.jboss.netty.channel.ChannelPipeline")); + } + + @Override + public String[] helperClassNames() { + return new String[] { + packageName + ".ChannelState", + // client helpers + packageName + ".client.NettyHttpClientDecorator", + packageName + ".client.NettyResponseInjectAdapter", + packageName + ".client.HttpClientRequestTracingHandler", + packageName + ".client.HttpClientResponseTracingHandler", + packageName + ".client.HttpClientTracingHandler", + // server helpers + packageName + ".server.NettyHttpServerDecorator", + packageName + ".server.NettyRequestExtractAdapter", + packageName + ".server.HttpServerRequestTracingHandler", + packageName + ".server.HttpServerResponseTracingHandler", + packageName + ".server.HttpServerTracingHandler" + }; + } + + @Override + public Map, String> transformers() { + final Map, String> transformers = new HashMap<>(); + transformers.put( + isMethod() + .and(nameStartsWith("add")) + .and(takesArgument(1, named("org.jboss.netty.channel.ChannelHandler"))), + NettyChannelPipelineInstrumentation.class.getName() + "$ChannelPipelineAdd2ArgsAdvice"); + transformers.put( + isMethod() + .and(nameStartsWith("add")) + .and(takesArgument(2, named("org.jboss.netty.channel.ChannelHandler"))), + NettyChannelPipelineInstrumentation.class.getName() + "$ChannelPipelineAdd3ArgsAdvice"); + return transformers; + } + + @Override + public Map contextStore() { + return Collections.singletonMap( + "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + } + + /** + * When certain handlers are added to the pipeline, we want to add our corresponding tracing + * handlers. If those handlers are later removed, we may want to remove our handlers. That is not + * currently implemented. + */ + public static class ChannelPipelineAdviceUtil { + public static void wrapHandler( + final ContextStore contextStore, + final ChannelPipeline pipeline, + final ChannelHandler handler) { + try { + // Server pipeline handlers + if (handler instanceof HttpServerCodec + && pipeline.get(HttpServerTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpServerTracingHandler.class.getName(), new HttpServerTracingHandler(contextStore)); + } else if (handler instanceof HttpRequestDecoder + && pipeline.get(HttpServerRequestTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpServerRequestTracingHandler.class.getName(), + new HttpServerRequestTracingHandler(contextStore)); + } else if (handler instanceof HttpResponseEncoder + && pipeline.get(HttpServerResponseTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpServerResponseTracingHandler.class.getName(), + new HttpServerResponseTracingHandler(contextStore)); + } else + // Client pipeline handlers + if (handler instanceof HttpClientCodec + && pipeline.get(HttpClientTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpClientTracingHandler.class.getName(), new HttpClientTracingHandler(contextStore)); + } else if (handler instanceof HttpRequestEncoder + && pipeline.get(HttpClientRequestTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpClientRequestTracingHandler.class.getName(), + new HttpClientRequestTracingHandler(contextStore)); + } else if (handler instanceof HttpResponseDecoder + && pipeline.get(HttpClientResponseTracingHandler.class.getName()) == null) { + pipeline.addLast( + HttpClientResponseTracingHandler.class.getName(), + new HttpClientResponseTracingHandler(contextStore)); + } + } catch (final IllegalArgumentException e) { + // Prevented adding duplicate handlers. + } finally { + CallDepthThreadLocalMap.reset(ChannelPipeline.class); + } + } + } + + public static class ChannelPipelineAdd2ArgsAdvice { + @Advice.OnMethodEnter + public static int checkDepth( + @Advice.This final ChannelPipeline pipeline, + @Advice.Argument(1) final ChannelHandler handler) { + if (pipeline.get(handler.getClass().getName()) != null) { + pipeline.remove(handler.getClass().getName()); + } + return CallDepthThreadLocalMap.incrementCallDepth(ChannelPipeline.class); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void addHandler( + @Advice.Enter final int depth, + @Advice.This final ChannelPipeline pipeline, + @Advice.Argument(1) final ChannelHandler handler) { + if (depth > 0) { + return; + } + + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelState.class); + + ChannelPipelineAdviceUtil.wrapHandler(contextStore, pipeline, handler); + } + } + + public static class ChannelPipelineAdd3ArgsAdvice { + @Advice.OnMethodEnter + public static int checkDepth( + @Advice.This final ChannelPipeline pipeline, + @Advice.Argument(2) final ChannelHandler handler) { + if (pipeline.get(handler.getClass().getName()) != null) { + pipeline.remove(handler.getClass().getName()); + } + return CallDepthThreadLocalMap.incrementCallDepth(ChannelPipeline.class); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void addHandler( + @Advice.Enter final int depth, + @Advice.This final ChannelPipeline pipeline, + @Advice.Argument(2) final ChannelHandler handler) { + if (depth > 0) { + return; + } + + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelState.class); + + ChannelPipelineAdviceUtil.wrapHandler(contextStore, pipeline, handler); + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java new file mode 100644 index 0000000000..1e2acd9e0b --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java @@ -0,0 +1,81 @@ +package datadog.trace.instrumentation.netty39.client; + +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator.DECORATE; +import static datadog.trace.instrumentation.netty39.client.NettyResponseInjectAdapter.SETTER; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.context.TraceScope; +import datadog.trace.instrumentation.netty39.ChannelState; +import java.net.InetSocketAddress; +import lombok.extern.slf4j.Slf4j; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelDownstreamHandler; +import org.jboss.netty.handler.codec.http.HttpRequest; + +@Slf4j +public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHandler { + + private final ContextStore contextStore; + + public HttpClientRequestTracingHandler(final ContextStore contextStore) { + this.contextStore = contextStore; + } + + @Override + public void writeRequested(final ChannelHandlerContext ctx, final MessageEvent msg) + throws Exception { + if (!(msg.getMessage() instanceof HttpRequest)) { + ctx.sendDownstream(msg); + return; + } + + final ChannelState channelState = + contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + + TraceScope parentScope = null; + final TraceScope.Continuation continuation = channelState.getConnectionContinuation(); + if (continuation != null) { + parentScope = continuation.activate(); + channelState.setConnectionContinuation(null); + } + + final HttpRequest request = (HttpRequest) msg.getMessage(); + + channelState.setClientParentSpan(activeSpan()); + + final AgentSpan span = startSpan("netty.client.request"); + try (final AgentScope scope = activateSpan(span, false)) { + DECORATE.afterStart(span); + DECORATE.onRequest(span, request); + DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.getChannel().getRemoteAddress()); + + // AWS calls are often signed, so we can't add headers without breaking the signature. + if (!request.headers().contains("amz-sdk-invocation-id")) { + propagate().inject(span, request.headers(), SETTER); + } + + channelState.setClientSpan(span); + + try { + ctx.sendDownstream(msg); + } catch (final Throwable throwable) { + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); + throw throwable; + } + } + + if (null != parentScope) { + parentScope.close(); + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java new file mode 100644 index 0000000000..db8e4db40d --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java @@ -0,0 +1,54 @@ +package datadog.trace.instrumentation.netty39.client; + +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopSpan; +import static datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator.DECORATE; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.instrumentation.netty39.ChannelState; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.handler.codec.http.HttpResponse; + +public class HttpClientResponseTracingHandler extends SimpleChannelUpstreamHandler { + + private final ContextStore contextStore; + + public HttpClientResponseTracingHandler(final ContextStore contextStore) { + this.contextStore = contextStore; + } + + @Override + public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent msg) + throws Exception { + final ChannelState channelState = + contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + + AgentSpan parent = channelState.getClientParentSpan(); + if (parent == null) { + parent = noopSpan(); + channelState.setClientParentSpan(noopSpan()); + } + final AgentSpan span = channelState.getClientSpan(); + + final boolean finishSpan = msg.getMessage() instanceof HttpResponse; + + if (span != null && finishSpan) { + try (final AgentScope scope = activateSpan(span, false)) { + DECORATE.onResponse(span, (HttpResponse) msg.getMessage()); + DECORATE.beforeFinish(span); + span.finish(); + } + } + + // We want the callback in the scope of the parent, not the client span + try (final AgentScope scope = activateSpan(parent, false)) { + scope.setAsyncPropagation(true); + ctx.sendUpstream(msg); + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java new file mode 100644 index 0000000000..325249581a --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java @@ -0,0 +1,17 @@ +package datadog.trace.instrumentation.netty39.client; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; +import org.jboss.netty.channel.Channel; + +public class HttpClientTracingHandler + extends CombinedSimpleChannelHandler< + HttpClientResponseTracingHandler, HttpClientRequestTracingHandler> { + + public HttpClientTracingHandler(final ContextStore contextStore) { + super( + new HttpClientResponseTracingHandler(contextStore), + new HttpClientRequestTracingHandler(contextStore)); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java new file mode 100644 index 0000000000..9ee1c4ea0b --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java @@ -0,0 +1,45 @@ +package datadog.trace.instrumentation.netty39.client; + +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.bootstrap.instrumentation.decorator.HttpClientDecorator; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; + +@Slf4j +public class NettyHttpClientDecorator extends HttpClientDecorator { + public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-3.9"}; + } + + @Override + protected String component() { + return "netty-client"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.getMethod().getName(); + } + + @Override + protected URI url(final HttpRequest request) throws URISyntaxException { + final URI uri = new URI(request.getUri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + return new URI("http://" + request.headers().get(HOST) + request.getUri()); + } else { + return uri; + } + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.getStatus().getCode(); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java new file mode 100644 index 0000000000..985d7e5d5f --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java @@ -0,0 +1,14 @@ +package datadog.trace.instrumentation.netty39.client; + +import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; +import org.jboss.netty.handler.codec.http.HttpHeaders; + +public class NettyResponseInjectAdapter implements AgentPropagation.Setter { + + public static final NettyResponseInjectAdapter SETTER = new NettyResponseInjectAdapter(); + + @Override + public void set(final HttpHeaders headers, final String key, final String value) { + headers.set(key, value); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java new file mode 100644 index 0000000000..08c6724319 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java @@ -0,0 +1,71 @@ +package datadog.trace.instrumentation.netty39.server; + +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator.DECORATE; +import static datadog.trace.instrumentation.netty39.server.NettyRequestExtractAdapter.GETTER; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan.Context; +import datadog.trace.instrumentation.netty39.ChannelState; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.handler.codec.http.HttpRequest; + +public class HttpServerRequestTracingHandler extends SimpleChannelUpstreamHandler { + + private final ContextStore contextStore; + + public HttpServerRequestTracingHandler(final ContextStore contextStore) { + this.contextStore = contextStore; + } + + @Override + public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent msg) + throws Exception { + final ChannelState channelState = + contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + + if (!(msg.getMessage() instanceof HttpRequest)) { + final AgentSpan span = channelState.getServerSpan(); + if (span == null) { + ctx.sendUpstream(msg); // superclass does not throw + } else { + try (final AgentScope scope = activateSpan(span, false)) { + scope.setAsyncPropagation(true); + ctx.sendUpstream(msg); // superclass does not throw + } + } + return; + } + + final HttpRequest request = (HttpRequest) msg.getMessage(); + + final Context context = propagate().extract(request.headers(), GETTER); + + final AgentSpan span = startSpan("netty.request", context); + try (final AgentScope scope = activateSpan(span, false)) { + DECORATE.afterStart(span); + DECORATE.onConnection(span, ctx.getChannel()); + DECORATE.onRequest(span, request); + + scope.setAsyncPropagation(true); + + channelState.setServerSpan(span); + + try { + ctx.sendUpstream(msg); + } catch (final Throwable throwable) { + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); // Finish the span manually since finishSpanOnClose was false + throw throwable; + } + } + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java new file mode 100644 index 0000000000..aed1388be0 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java @@ -0,0 +1,49 @@ +package datadog.trace.instrumentation.netty39.server; + +import static datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator.DECORATE; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Tags; +import datadog.trace.instrumentation.netty39.ChannelState; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelDownstreamHandler; +import org.jboss.netty.handler.codec.http.HttpResponse; + +public class HttpServerResponseTracingHandler extends SimpleChannelDownstreamHandler { + + private final ContextStore contextStore; + + public HttpServerResponseTracingHandler(final ContextStore contextStore) { + this.contextStore = contextStore; + } + + @Override + public void writeRequested(final ChannelHandlerContext ctx, final MessageEvent msg) + throws Exception { + final ChannelState channelState = + contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + + final AgentSpan span = channelState.getServerSpan(); + if (span == null || !(msg.getMessage() instanceof HttpResponse)) { + ctx.sendDownstream(msg); + return; + } + + final HttpResponse response = (HttpResponse) msg.getMessage(); + + try { + ctx.sendDownstream(msg); + } catch (final Throwable throwable) { + DECORATE.onError(span, throwable); + span.setTag(Tags.HTTP_STATUS, 500); + span.finish(); // Finish the span manually since finishSpanOnClose was false + throw throwable; + } + DECORATE.onResponse(span, response); + DECORATE.beforeFinish(span); + span.finish(); // Finish the span manually since finishSpanOnClose was false + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java new file mode 100644 index 0000000000..0037028fa0 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java @@ -0,0 +1,17 @@ +package datadog.trace.instrumentation.netty39.server; + +import datadog.trace.bootstrap.ContextStore; +import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; +import org.jboss.netty.channel.Channel; + +public class HttpServerTracingHandler + extends CombinedSimpleChannelHandler< + HttpServerRequestTracingHandler, HttpServerResponseTracingHandler> { + + public HttpServerTracingHandler(final ContextStore contextStore) { + super( + new HttpServerRequestTracingHandler(contextStore), + new HttpServerResponseTracingHandler(contextStore)); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java new file mode 100644 index 0000000000..e51a9c6ea6 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java @@ -0,0 +1,67 @@ +package datadog.trace.instrumentation.netty39.server; + +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; + +@Slf4j +public class NettyHttpServerDecorator + extends HttpServerDecorator { + public static final NettyHttpServerDecorator DECORATE = new NettyHttpServerDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-3.9"}; + } + + @Override + protected String component() { + return "netty"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.getMethod().getName(); + } + + @Override + protected URI url(final HttpRequest request) throws URISyntaxException { + final URI uri = new URI(request.getUri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + return new URI("http://" + request.headers().get(HOST) + request.getUri()); + } else { + return uri; + } + } + + @Override + protected String peerHostIP(final Channel channel) { + final SocketAddress socketAddress = channel.getRemoteAddress(); + if (socketAddress instanceof InetSocketAddress) { + return ((InetSocketAddress) socketAddress).getAddress().getHostAddress(); + } + return null; + } + + @Override + protected Integer peerPort(final Channel channel) { + final SocketAddress socketAddress = channel.getRemoteAddress(); + if (socketAddress instanceof InetSocketAddress) { + return ((InetSocketAddress) socketAddress).getPort(); + } + return null; + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.getStatus().getCode(); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java new file mode 100644 index 0000000000..3834d3209f --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java @@ -0,0 +1,19 @@ +package datadog.trace.instrumentation.netty39.server; + +import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; +import org.jboss.netty.handler.codec.http.HttpHeaders; + +public class NettyRequestExtractAdapter implements AgentPropagation.Getter { + + public static final NettyRequestExtractAdapter GETTER = new NettyRequestExtractAdapter(); + + @Override + public Iterable keys(final HttpHeaders headers) { + return headers.names(); + } + + @Override + public String get(final HttpHeaders headers, final String key) { + return headers.get(key); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java new file mode 100644 index 0000000000..2823bfe72a --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java @@ -0,0 +1,152 @@ +package datadog.trace.instrumentation.netty39.util; + +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ChildChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelDownstreamHandler; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.channel.WriteCompletionEvent; + +public class CombinedSimpleChannelHandler< + Upstream extends SimpleChannelUpstreamHandler, + Downstream extends SimpleChannelDownstreamHandler> + extends SimpleChannelHandler { + + private final Upstream upstream; + private final Downstream downstream; + + public CombinedSimpleChannelHandler(final Upstream upstream, final Downstream downstream) { + this.upstream = upstream; + this.downstream = downstream; + } + + @Override + public void handleUpstream(final ChannelHandlerContext ctx, final ChannelEvent e) + throws Exception { + upstream.handleUpstream(ctx, e); + } + + @Override + public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e) + throws Exception { + upstream.messageReceived(ctx, e); + } + + @Override + public void exceptionCaught(final ChannelHandlerContext ctx, final ExceptionEvent e) + throws Exception { + upstream.exceptionCaught(ctx, e); + } + + @Override + public void channelOpen(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelOpen(ctx, e); + } + + @Override + public void channelBound(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelBound(ctx, e); + } + + @Override + public void channelConnected(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelConnected(ctx, e); + } + + @Override + public void channelInterestChanged(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelInterestChanged(ctx, e); + } + + @Override + public void channelDisconnected(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelDisconnected(ctx, e); + } + + @Override + public void channelUnbound(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelUnbound(ctx, e); + } + + @Override + public void channelClosed(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + upstream.channelClosed(ctx, e); + } + + @Override + public void writeComplete(final ChannelHandlerContext ctx, final WriteCompletionEvent e) + throws Exception { + upstream.writeComplete(ctx, e); + } + + @Override + public void childChannelOpen(final ChannelHandlerContext ctx, final ChildChannelStateEvent e) + throws Exception { + upstream.childChannelOpen(ctx, e); + } + + @Override + public void childChannelClosed(final ChannelHandlerContext ctx, final ChildChannelStateEvent e) + throws Exception { + upstream.childChannelClosed(ctx, e); + } + + @Override + public void handleDownstream(final ChannelHandlerContext ctx, final ChannelEvent e) + throws Exception { + downstream.handleDownstream(ctx, e); + } + + @Override + public void writeRequested(final ChannelHandlerContext ctx, final MessageEvent e) + throws Exception { + downstream.writeRequested(ctx, e); + } + + @Override + public void bindRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.bindRequested(ctx, e); + } + + @Override + public void connectRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.connectRequested(ctx, e); + } + + @Override + public void setInterestOpsRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.setInterestOpsRequested(ctx, e); + } + + @Override + public void disconnectRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.disconnectRequested(ctx, e); + } + + @Override + public void unbindRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.unbindRequested(ctx, e); + } + + @Override + public void closeRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e) + throws Exception { + downstream.closeRequested(ctx, e); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy new file mode 100644 index 0000000000..25ebbe0ac2 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy @@ -0,0 +1,103 @@ +import com.ning.http.client.AsyncCompletionHandler +import com.ning.http.client.AsyncHttpClient +import com.ning.http.client.AsyncHttpClientConfig +import com.ning.http.client.Response +import datadog.trace.agent.test.base.HttpClientTest +import datadog.trace.bootstrap.instrumentation.api.Tags +import datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator +import spock.lang.AutoCleanup +import spock.lang.Shared + +import java.util.concurrent.ExecutionException +import java.util.concurrent.TimeUnit + +import static datadog.trace.agent.test.utils.PortUtils.UNUSABLE_PORT +import static datadog.trace.agent.test.utils.TraceUtils.basicSpan +import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace + +class Netty39ClientTest extends HttpClientTest { + + @Shared + def clientConfig = new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(TimeUnit.SECONDS.toMillis(10).toInteger()).build() + @Shared + @AutoCleanup + AsyncHttpClient asyncHttpClient = new AsyncHttpClient(clientConfig) + + @Override + int doRequest(String method, URI uri, Map headers, Closure callback) { + def methodName = "prepare" + method.toLowerCase().capitalize() + def requestBuilder = asyncHttpClient."$methodName"(uri.toString()) + headers.each { requestBuilder.setHeader(it.key, it.value) } + def response = requestBuilder.execute(new AsyncCompletionHandler() { + @Override + Object onCompleted(Response response) throws Exception { + callback?.call() + return response + } + }).get() + blockUntilChildSpansFinished(1) + return response.statusCode + } + + @Override + String component() { + return NettyHttpClientDecorator.DECORATE.component() + } + + @Override + String expectedOperationName() { + return "netty.client.request" + } + + @Override + boolean testRedirects() { + false + } + + @Override + boolean testConnectionFailure() { + false + } + + def "connection error (unopened port)"() { + given: + def uri = new URI("http://localhost:$UNUSABLE_PORT/") + + when: + runUnderTrace("parent") { + doRequest(method, uri) + } + + then: + def ex = thrown(Exception) + def thrownException = ex instanceof ExecutionException ? ex.cause : ex + + and: + assertTraces(1) { + trace(0, 2) { + basicSpan(it, 0, "parent", null, thrownException) + + span(1) { + operationName "netty.connect" + resourceName "netty.connect" + childOf span(0) + errored true + tags { + "$Tags.COMPONENT" "netty" + Class errorClass = ConnectException + try { + errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException') + } catch (ClassNotFoundException e) { + // Older versions use 'java.net.ConnectException' and do not have 'io.netty.channel.AbstractChannel$AnnotatedConnectException' + } + errorTags errorClass, "Connection refused: localhost/127.0.0.1:$UNUSABLE_PORT" + defaultTags() + } + } + } + } + + where: + method = "GET" + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy new file mode 100644 index 0000000000..ab76a536b1 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy @@ -0,0 +1,111 @@ +import datadog.trace.agent.test.base.HttpServerTest +import datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator +import org.jboss.netty.bootstrap.ServerBootstrap +import org.jboss.netty.buffer.ChannelBuffer +import org.jboss.netty.buffer.ChannelBuffers +import org.jboss.netty.channel.* +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory +import org.jboss.netty.handler.codec.http.* +import org.jboss.netty.handler.logging.LoggingHandler +import org.jboss.netty.logging.InternalLogLevel +import org.jboss.netty.util.CharsetUtil + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.* +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.* +import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1 + +class Netty39ServerTest extends HttpServerTest { + + ChannelPipeline channelPipeline() { + ChannelPipeline channelPipeline = new DefaultChannelPipeline() + + channelPipeline.addLast("http-codec", new HttpServerCodec()) + channelPipeline.addLast("controller", new SimpleChannelHandler() { + @Override + void messageReceived(ChannelHandlerContext ctx, MessageEvent msg) throws Exception { + if (msg.getMessage() instanceof HttpRequest) { + def uri = URI.create((msg.getMessage() as HttpRequest).getUri()) + HttpServerTest.ServerEndpoint endpoint = forPath(uri.path) + ctx.sendDownstream controller(endpoint) { + HttpResponse response + ChannelBuffer responseContent = null + switch (endpoint) { + case SUCCESS: + case ERROR: + responseContent = ChannelBuffers.copiedBuffer(endpoint.body, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + case QUERY_PARAM: + responseContent = ChannelBuffers.copiedBuffer(uri.query, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + case REDIRECT: + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.headers().set(LOCATION, endpoint.body) + break + case EXCEPTION: + throw new Exception(endpoint.body) + default: + responseContent = ChannelBuffers.copiedBuffer(NOT_FOUND.body, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + } + response.headers().set(CONTENT_TYPE, "text/plain") + if (responseContent) { + response.headers().set(CONTENT_LENGTH, responseContent.readableBytes()) + } + return new DownstreamMessageEvent( + ctx.getChannel(), + new SucceededChannelFuture(ctx.getChannel()), + response, + ctx.getChannel().getRemoteAddress()) + } + } + } + + @Override + void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent ex) throws Exception { + ChannelBuffer buffer = ChannelBuffers.copiedBuffer(ex.getCause().getMessage(), CharsetUtil.UTF_8) + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR) + response.setContent(buffer) + response.headers().set(CONTENT_TYPE, "text/plain") + response.headers().set(CONTENT_LENGTH, buffer.readableBytes()) + ctx.sendDownstream(new DownstreamMessageEvent( + ctx.getChannel(), + new FailedChannelFuture(ctx.getChannel(), ex.getCause()), + response, + ctx.getChannel().getRemoteAddress())) + } + }) + + return channelPipeline + } + + @Override + Channel startServer(int port) { + ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory()) + bootstrap.setParentHandler(new LoggingHandler(InternalLogLevel.INFO)) + bootstrap.setPipeline(channelPipeline()) + + InetSocketAddress address = new InetSocketAddress(port) + return bootstrap.bind(address) + } + + @Override + void stopServer(Channel server) { + server?.disconnect() + } + + @Override + String component() { + NettyHttpServerDecorator.DECORATE.component() + } + + @Override + String expectedOperationName() { + "netty.request" + } +} diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java new file mode 100644 index 0000000000..9657cea79c --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java @@ -0,0 +1,21 @@ +import static net.bytebuddy.matcher.ElementMatchers.named; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.test.base.HttpServerTestAdvice; +import datadog.trace.agent.tooling.Instrumenter; +import net.bytebuddy.agent.builder.AgentBuilder; + +@AutoService(Instrumenter.class) +public class NettyServerTestInstrumentation implements Instrumenter { + + @Override + public AgentBuilder instrument(final AgentBuilder agentBuilder) { + return agentBuilder + .type(named("org.jboss.netty.handler.codec.http.HttpRequestDecoder")) + .transform( + new AgentBuilder.Transformer.ForAdvice() + .advice( + named("createMessage"), + HttpServerTestAdvice.ServerEntryAdvice.class.getName())); + } +} From 7e45aa731f9409bd51d0d1be8a57d515a1b7bef6 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 05:36:52 -0400 Subject: [PATCH 02/15] Add module --- settings.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.gradle b/settings.gradle index 75240bee25..0fd80a9c09 100644 --- a/settings.gradle +++ b/settings.gradle @@ -112,6 +112,7 @@ include ':dd-java-agent:instrumentation:log4j2' include ':dd-java-agent:instrumentation:mongo' include ':dd-java-agent:instrumentation:mongo:driver-3.1' include ':dd-java-agent:instrumentation:mongo:driver-async-3.3' +include ':dd-java-agent:instrumentation:netty-3.9' include ':dd-java-agent:instrumentation:netty-4.0' include ':dd-java-agent:instrumentation:netty-4.1' include ':dd-java-agent:instrumentation:okhttp-3' From baf02ff526e6c88bee3317bd83896c6afd680560 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 05:41:35 -0400 Subject: [PATCH 03/15] Remove unneccesary checks --- .../NettyChannelPipelineInstrumentation.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java index e78313d40a..b747c20d4f 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java @@ -109,33 +109,27 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { final ChannelHandler handler) { try { // Server pipeline handlers - if (handler instanceof HttpServerCodec - && pipeline.get(HttpServerTracingHandler.class.getName()) == null) { + if (handler instanceof HttpServerCodec) { pipeline.addLast( HttpServerTracingHandler.class.getName(), new HttpServerTracingHandler(contextStore)); - } else if (handler instanceof HttpRequestDecoder - && pipeline.get(HttpServerRequestTracingHandler.class.getName()) == null) { + } else if (handler instanceof HttpRequestDecoder) { pipeline.addLast( HttpServerRequestTracingHandler.class.getName(), new HttpServerRequestTracingHandler(contextStore)); - } else if (handler instanceof HttpResponseEncoder - && pipeline.get(HttpServerResponseTracingHandler.class.getName()) == null) { + } else if (handler instanceof HttpResponseEncoder) { pipeline.addLast( HttpServerResponseTracingHandler.class.getName(), new HttpServerResponseTracingHandler(contextStore)); } else // Client pipeline handlers - if (handler instanceof HttpClientCodec - && pipeline.get(HttpClientTracingHandler.class.getName()) == null) { + if (handler instanceof HttpClientCodec) { pipeline.addLast( HttpClientTracingHandler.class.getName(), new HttpClientTracingHandler(contextStore)); - } else if (handler instanceof HttpRequestEncoder - && pipeline.get(HttpClientRequestTracingHandler.class.getName()) == null) { + } else if (handler instanceof HttpRequestEncoder) { pipeline.addLast( HttpClientRequestTracingHandler.class.getName(), new HttpClientRequestTracingHandler(contextStore)); - } else if (handler instanceof HttpResponseDecoder - && pipeline.get(HttpClientResponseTracingHandler.class.getName()) == null) { + } else if (handler instanceof HttpResponseDecoder) { pipeline.addLast( HttpClientResponseTracingHandler.class.getName(), new HttpClientResponseTracingHandler(contextStore)); From 2d84dd7eecf6bc0a006e7783838d59d18066527c Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 05:45:09 -0400 Subject: [PATCH 04/15] Add a comment for a special case to this netty version --- .../netty39/NettyChannelPipelineInstrumentation.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java index b747c20d4f..9174ec93ca 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java @@ -147,6 +147,9 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { public static int checkDepth( @Advice.This final ChannelPipeline pipeline, @Advice.Argument(1) final 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()); } @@ -174,6 +177,9 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { public static int checkDepth( @Advice.This final ChannelPipeline pipeline, @Advice.Argument(2) final 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()); } From 8e4f9c4dc6943ff69f13d27b88c0da37bfa7dcba Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 05:52:16 -0400 Subject: [PATCH 05/15] refine gradle config --- dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle b/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle index d36edb443a..a467162d93 100644 --- a/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle +++ b/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle @@ -10,7 +10,7 @@ muzzle { pass { group = "io.netty" module = "netty" - versions = "[3.9.0.Final,4)" + versions = "[3.9.0.Final,3.10)" assertInverse = true } fail { @@ -34,7 +34,7 @@ dependencies { testCompile group: 'io.netty', name: 'netty', version: '3.9.0.Final' testCompile group: 'com.ning', name: 'async-http-client', version: '1.8.0' - latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.9.9.Final' + latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.9.+' latestDepTestCompile group: 'com.ning', name: 'async-http-client', version: '1.8.+' } From eb99b410c57cd95140b330588115eb3cd556f606 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 06:25:26 -0400 Subject: [PATCH 06/15] gross hack for muzzle --- .../netty39/ChannelFutureListenerInstrumentation.java | 7 ++++++- .../netty39/NettyChannelInstrumentation.java | 8 ++++++-- .../netty39/NettyChannelPipelineInstrumentation.java | 10 +++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java index 85b9977046..a0682c3c95 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java @@ -39,7 +39,11 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed("org.jboss.netty.channel.ChannelFutureListener"); + return hasClassesNamed( + "org.jboss.netty.channel.ChannelFutureListener", + "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 + "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 + ); } @Override @@ -51,6 +55,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".ChannelState", + packageName + ".ChannelState$Factory", packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter" }; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java index e3f51ea34d..1be3b2bcc1 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java @@ -32,7 +32,11 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed("org.jboss.netty.channel.Channel"); + return hasClassesNamed( + "org.jboss.netty.channel.Channel", + "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 + "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 + ); } @Override @@ -42,7 +46,7 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { - return new String[] {packageName + ".ChannelState"}; + return new String[] {packageName + ".ChannelState", packageName + ".ChannelState$Factory"}; } @Override diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java index 9174ec93ca..5a5530d465 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java @@ -48,7 +48,11 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed("org.jboss.netty.channel.ChannelPipeline"); + return hasClassesNamed( + "org.jboss.netty.channel.ChannelPipeline", + "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 + "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 + ); } @Override @@ -60,6 +64,10 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".ChannelState", + packageName + ".ChannelState$Factory", + NettyChannelPipelineInstrumentation.class.getName() + "$ChannelPipelineAdviceUtil", + // Util + packageName + ".util.CombinedSimpleChannelHandler", // client helpers packageName + ".client.NettyHttpClientDecorator", packageName + ".client.NettyResponseInjectAdapter", From 9297ff39f47b797a9990b169692234144e66bfb6 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 08:00:34 -0400 Subject: [PATCH 07/15] Less ambiguous name, also doesn't collide with netty class --- .../ChannelFutureListenerInstrumentation.java | 12 ++++++------ ...nelState.java => ChannelTraceContext.java} | 8 ++++---- .../netty39/NettyChannelInstrumentation.java | 12 +++++++----- .../NettyChannelPipelineInstrumentation.java | 16 ++++++++-------- .../HttpClientRequestTracingHandler.java | 19 ++++++++++--------- .../HttpClientResponseTracingHandler.java | 17 +++++++++-------- .../client/HttpClientTracingHandler.java | 4 ++-- .../HttpServerRequestTracingHandler.java | 15 ++++++++------- .../HttpServerResponseTracingHandler.java | 13 +++++++------ .../server/HttpServerTracingHandler.java | 4 ++-- 10 files changed, 63 insertions(+), 57 deletions(-) rename dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/{ChannelState.java => ChannelTraceContext.java} (87%) diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java index a0682c3c95..e5cec85663 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java @@ -54,8 +54,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { return new String[] { - packageName + ".ChannelState", - packageName + ".ChannelState$Factory", + packageName + ".ChannelTraceContext", + packageName + ".ChannelTraceContext$Factory", packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter" }; @@ -73,7 +73,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public Map contextStore() { return Collections.singletonMap( - "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); } public static class OperationCompleteAdvice { @@ -89,12 +89,12 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { return null; } - final ContextStore contextStore = - InstrumentationContext.get(Channel.class, ChannelState.class); + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelTraceContext.class); final TraceScope.Continuation continuation = contextStore - .putIfAbsent(future.getChannel(), ChannelState.Factory.INSTANCE) + .putIfAbsent(future.getChannel(), ChannelTraceContext.Factory.INSTANCE) .getConnectionContinuationAndRemove(); if (continuation == null) { return null; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java similarity index 87% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java rename to dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java index 3c19f4ebb6..e021002b6c 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelState.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java @@ -6,13 +6,13 @@ import datadog.trace.context.TraceScope; import lombok.Data; @Data -public class ChannelState { - public static class Factory implements ContextStore.Factory { +public class ChannelTraceContext { + public static class Factory implements ContextStore.Factory { public static final Factory INSTANCE = new Factory(); @Override - public ChannelState create() { - return new ChannelState(); + public ChannelTraceContext create() { + return new ChannelTraceContext(); } } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java index 1be3b2bcc1..b242b88e8d 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java @@ -46,7 +46,9 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { - return new String[] {packageName + ".ChannelState", packageName + ".ChannelState$Factory"}; + return new String[] { + packageName + ".ChannelTraceContext", packageName + ".ChannelTraceContext$Factory" + }; } @Override @@ -63,7 +65,7 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public Map contextStore() { return Collections.singletonMap( - "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); } public static class ChannelConnectAdvice { @@ -73,11 +75,11 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { if (scope != null) { final TraceScope.Continuation continuation = scope.capture(); if (continuation != null) { - final ContextStore contextStore = - InstrumentationContext.get(Channel.class, ChannelState.class); + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelTraceContext.class); if (!contextStore - .putIfAbsent(channel, ChannelState.Factory.INSTANCE) + .putIfAbsent(channel, ChannelTraceContext.Factory.INSTANCE) .compareAndSet(null, continuation)) { continuation.close(); } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java index 5a5530d465..697cf14a02 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java @@ -63,8 +63,8 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { return new String[] { - packageName + ".ChannelState", - packageName + ".ChannelState$Factory", + packageName + ".ChannelTraceContext", + packageName + ".ChannelTraceContext$Factory", NettyChannelPipelineInstrumentation.class.getName() + "$ChannelPipelineAdviceUtil", // Util packageName + ".util.CombinedSimpleChannelHandler", @@ -102,7 +102,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { @Override public Map contextStore() { return Collections.singletonMap( - "org.jboss.netty.channel.Channel", ChannelState.class.getName()); + "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); } /** @@ -112,7 +112,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { */ public static class ChannelPipelineAdviceUtil { public static void wrapHandler( - final ContextStore contextStore, + final ContextStore contextStore, final ChannelPipeline pipeline, final ChannelHandler handler) { try { @@ -173,8 +173,8 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { return; } - final ContextStore contextStore = - InstrumentationContext.get(Channel.class, ChannelState.class); + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelTraceContext.class); ChannelPipelineAdviceUtil.wrapHandler(contextStore, pipeline, handler); } @@ -203,8 +203,8 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { return; } - final ContextStore contextStore = - InstrumentationContext.get(Channel.class, ChannelState.class); + final ContextStore contextStore = + InstrumentationContext.get(Channel.class, ChannelTraceContext.class); ChannelPipelineAdviceUtil.wrapHandler(contextStore, pipeline, handler); } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java index 1e2acd9e0b..df5fd3e079 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java @@ -11,7 +11,7 @@ import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.context.TraceScope; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import java.net.InetSocketAddress; import lombok.extern.slf4j.Slf4j; import org.jboss.netty.channel.Channel; @@ -23,9 +23,10 @@ import org.jboss.netty.handler.codec.http.HttpRequest; @Slf4j public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHandler { - private final ContextStore contextStore; + private final ContextStore contextStore; - public HttpClientRequestTracingHandler(final ContextStore contextStore) { + public HttpClientRequestTracingHandler( + final ContextStore contextStore) { this.contextStore = contextStore; } @@ -37,19 +38,19 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand return; } - final ChannelState channelState = - contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + final ChannelTraceContext channelTraceContext = + contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE); TraceScope parentScope = null; - final TraceScope.Continuation continuation = channelState.getConnectionContinuation(); + final TraceScope.Continuation continuation = channelTraceContext.getConnectionContinuation(); if (continuation != null) { parentScope = continuation.activate(); - channelState.setConnectionContinuation(null); + channelTraceContext.setConnectionContinuation(null); } final HttpRequest request = (HttpRequest) msg.getMessage(); - channelState.setClientParentSpan(activeSpan()); + channelTraceContext.setClientParentSpan(activeSpan()); final AgentSpan span = startSpan("netty.client.request"); try (final AgentScope scope = activateSpan(span, false)) { @@ -62,7 +63,7 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand propagate().inject(span, request.headers(), SETTER); } - channelState.setClientSpan(span); + channelTraceContext.setClientSpan(span); try { ctx.sendDownstream(msg); diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java index db8e4db40d..ebd5f6fc66 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java @@ -7,7 +7,7 @@ import static datadog.trace.instrumentation.netty39.client.NettyHttpClientDecora import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; @@ -16,24 +16,25 @@ import org.jboss.netty.handler.codec.http.HttpResponse; public class HttpClientResponseTracingHandler extends SimpleChannelUpstreamHandler { - private final ContextStore contextStore; + private final ContextStore contextStore; - public HttpClientResponseTracingHandler(final ContextStore contextStore) { + public HttpClientResponseTracingHandler( + final ContextStore contextStore) { this.contextStore = contextStore; } @Override public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent msg) throws Exception { - final ChannelState channelState = - contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + final ChannelTraceContext channelTraceContext = + contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE); - AgentSpan parent = channelState.getClientParentSpan(); + AgentSpan parent = channelTraceContext.getClientParentSpan(); if (parent == null) { parent = noopSpan(); - channelState.setClientParentSpan(noopSpan()); + channelTraceContext.setClientParentSpan(noopSpan()); } - final AgentSpan span = channelState.getClientSpan(); + final AgentSpan span = channelTraceContext.getClientSpan(); final boolean finishSpan = msg.getMessage() instanceof HttpResponse; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java index 325249581a..7e0efa27d9 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java @@ -1,7 +1,7 @@ package datadog.trace.instrumentation.netty39.client; import datadog.trace.bootstrap.ContextStore; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; import org.jboss.netty.channel.Channel; @@ -9,7 +9,7 @@ public class HttpClientTracingHandler extends CombinedSimpleChannelHandler< HttpClientResponseTracingHandler, HttpClientRequestTracingHandler> { - public HttpClientTracingHandler(final ContextStore contextStore) { + public HttpClientTracingHandler(final ContextStore contextStore) { super( new HttpClientResponseTracingHandler(contextStore), new HttpClientRequestTracingHandler(contextStore)); diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java index 08c6724319..33acba335f 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java @@ -10,7 +10,7 @@ import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentSpan.Context; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; @@ -19,20 +19,21 @@ import org.jboss.netty.handler.codec.http.HttpRequest; public class HttpServerRequestTracingHandler extends SimpleChannelUpstreamHandler { - private final ContextStore contextStore; + private final ContextStore contextStore; - public HttpServerRequestTracingHandler(final ContextStore contextStore) { + public HttpServerRequestTracingHandler( + final ContextStore contextStore) { this.contextStore = contextStore; } @Override public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent msg) throws Exception { - final ChannelState channelState = - contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + final ChannelTraceContext channelTraceContext = + contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE); if (!(msg.getMessage() instanceof HttpRequest)) { - final AgentSpan span = channelState.getServerSpan(); + final AgentSpan span = channelTraceContext.getServerSpan(); if (span == null) { ctx.sendUpstream(msg); // superclass does not throw } else { @@ -56,7 +57,7 @@ public class HttpServerRequestTracingHandler extends SimpleChannelUpstreamHandle scope.setAsyncPropagation(true); - channelState.setServerSpan(span); + channelTraceContext.setServerSpan(span); try { ctx.sendUpstream(msg); diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java index aed1388be0..3b3104a782 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java @@ -5,7 +5,7 @@ import static datadog.trace.instrumentation.netty39.server.NettyHttpServerDecora import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.Tags; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; @@ -14,19 +14,20 @@ import org.jboss.netty.handler.codec.http.HttpResponse; public class HttpServerResponseTracingHandler extends SimpleChannelDownstreamHandler { - private final ContextStore contextStore; + private final ContextStore contextStore; - public HttpServerResponseTracingHandler(final ContextStore contextStore) { + public HttpServerResponseTracingHandler( + final ContextStore contextStore) { this.contextStore = contextStore; } @Override public void writeRequested(final ChannelHandlerContext ctx, final MessageEvent msg) throws Exception { - final ChannelState channelState = - contextStore.putIfAbsent(ctx.getChannel(), ChannelState.Factory.INSTANCE); + final ChannelTraceContext channelTraceContext = + contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE); - final AgentSpan span = channelState.getServerSpan(); + final AgentSpan span = channelTraceContext.getServerSpan(); if (span == null || !(msg.getMessage() instanceof HttpResponse)) { ctx.sendDownstream(msg); return; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java index 0037028fa0..c11867d0ea 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java @@ -1,7 +1,7 @@ package datadog.trace.instrumentation.netty39.server; import datadog.trace.bootstrap.ContextStore; -import datadog.trace.instrumentation.netty39.ChannelState; +import datadog.trace.instrumentation.netty39.ChannelTraceContext; import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; import org.jboss.netty.channel.Channel; @@ -9,7 +9,7 @@ public class HttpServerTracingHandler extends CombinedSimpleChannelHandler< HttpServerRequestTracingHandler, HttpServerResponseTracingHandler> { - public HttpServerTracingHandler(final ContextStore contextStore) { + public HttpServerTracingHandler(final ContextStore contextStore) { super( new HttpServerRequestTracingHandler(contextStore), new HttpServerResponseTracingHandler(contextStore)); From 4ae71c8087c84c257690a7631b3ee157098c450b Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 14:11:53 -0400 Subject: [PATCH 08/15] Works with 3.8 also, still need to fix muzzle again --- .../netty-3.8.gradle} | 8 ++++---- .../ChannelFutureListenerInstrumentation.java | 5 ++--- .../netty38}/ChannelTraceContext.java | 2 +- .../netty38}/NettyChannelInstrumentation.java | 7 +++---- .../NettyChannelPipelineInstrumentation.java | 15 +++++++-------- .../client/HttpClientRequestTracingHandler.java | 8 ++++---- .../client/HttpClientResponseTracingHandler.java | 6 +++--- .../netty38}/client/HttpClientTracingHandler.java | 6 +++--- .../netty38}/client/NettyHttpClientDecorator.java | 2 +- .../client/NettyResponseInjectAdapter.java | 2 +- .../server/HttpServerRequestTracingHandler.java | 8 ++++---- .../server/HttpServerResponseTracingHandler.java | 6 +++--- .../netty38}/server/HttpServerTracingHandler.java | 6 +++--- .../netty38}/server/NettyHttpServerDecorator.java | 2 +- .../server/NettyRequestExtractAdapter.java | 2 +- .../util/CombinedSimpleChannelHandler.java | 2 +- .../src/test/groovy/Netty39ClientTest.groovy | 2 +- .../src/test/groovy/Netty39ServerTest.groovy | 2 +- .../groovy/NettyServerTestInstrumentation.java | 0 settings.gradle | 2 +- 20 files changed, 45 insertions(+), 48 deletions(-) rename dd-java-agent/instrumentation/{netty-3.9/netty-3.9.gradle => netty-3.8/netty-3.8.gradle} (84%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/ChannelFutureListenerInstrumentation.java (96%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/ChannelTraceContext.java (95%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/NettyChannelInstrumentation.java (93%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/NettyChannelPipelineInstrumentation.java (94%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/client/HttpClientRequestTracingHandler.java (92%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/client/HttpClientResponseTracingHandler.java (91%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/client/HttpClientTracingHandler.java (73%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/client/NettyHttpClientDecorator.java (96%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/client/NettyResponseInjectAdapter.java (89%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/server/HttpServerRequestTracingHandler.java (91%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/server/HttpServerResponseTracingHandler.java (90%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/server/HttpServerTracingHandler.java (73%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/server/NettyHttpServerDecorator.java (97%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/server/NettyRequestExtractAdapter.java (90%) rename dd-java-agent/instrumentation/{netty-3.9/src/main/java/datadog/trace/instrumentation/netty39 => netty-3.8/src/main/java/datadog/trace/instrumentation/netty38}/util/CombinedSimpleChannelHandler.java (98%) rename dd-java-agent/instrumentation/{netty-3.9 => netty-3.8}/src/test/groovy/Netty39ClientTest.groovy (97%) rename dd-java-agent/instrumentation/{netty-3.9 => netty-3.8}/src/test/groovy/Netty39ServerTest.groovy (98%) rename dd-java-agent/instrumentation/{netty-3.9 => netty-3.8}/src/test/groovy/NettyServerTestInstrumentation.java (100%) diff --git a/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle b/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle similarity index 84% rename from dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle rename to dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle index a467162d93..d706cd806b 100644 --- a/dd-java-agent/instrumentation/netty-3.9/netty-3.9.gradle +++ b/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle @@ -10,7 +10,7 @@ muzzle { pass { group = "io.netty" module = "netty" - versions = "[3.9.0.Final,3.10)" + versions = "[3.8.0.Final,3.10)" assertInverse = true } fail { @@ -29,9 +29,9 @@ testSets { } dependencies { - compileOnly group: 'io.netty', name: 'netty', version: '3.9.0.Final' + compileOnly group: 'io.netty', name: 'netty', version: '3.8.0.Final' - testCompile group: 'io.netty', name: 'netty', version: '3.9.0.Final' + testCompile group: 'io.netty', name: 'netty', version: '3.8.0.Final' testCompile group: 'com.ning', name: 'async-http-client', version: '1.8.0' latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.9.+' @@ -44,7 +44,7 @@ configurations.testCompile { eachDependency { DependencyResolveDetails details -> //specifying a fixed version for all libraries with io.netty' group if (details.requested.group == 'io.netty') { - details.useVersion "3.9.0.Final" + details.useVersion "3.8.0.Final" } } } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java similarity index 96% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index e5cec85663..224d04650a 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39; +package datadog.trace.instrumentation.netty38; import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; @@ -17,7 +17,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.context.TraceScope; -import datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator; +import datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator; import java.util.Collections; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -41,7 +41,6 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.ChannelFutureListener", - "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java similarity index 95% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java index e021002b6c..1bba8ba74a 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/ChannelTraceContext.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39; +package datadog.trace.instrumentation.netty38; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java similarity index 93% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index b242b88e8d..7619f91e7a 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -1,10 +1,10 @@ -package datadog.trace.instrumentation.netty39; +package datadog.trace.instrumentation.netty38; import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope; -import static datadog.trace.instrumentation.netty39.NettyChannelPipelineInstrumentation.ADDITIONAL_INSTRUMENTATION_NAMES; -import static datadog.trace.instrumentation.netty39.NettyChannelPipelineInstrumentation.INSTRUMENTATION_NAME; +import static datadog.trace.instrumentation.netty38.NettyChannelPipelineInstrumentation.ADDITIONAL_INSTRUMENTATION_NAMES; +import static datadog.trace.instrumentation.netty38.NettyChannelPipelineInstrumentation.INSTRUMENTATION_NAME; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.returns; @@ -34,7 +34,6 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.Channel", - "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java similarity index 94% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java index 697cf14a02..dea115942b 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39; +package datadog.trace.instrumentation.netty38; import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; @@ -12,12 +12,12 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.InstrumentationContext; -import datadog.trace.instrumentation.netty39.client.HttpClientRequestTracingHandler; -import datadog.trace.instrumentation.netty39.client.HttpClientResponseTracingHandler; -import datadog.trace.instrumentation.netty39.client.HttpClientTracingHandler; -import datadog.trace.instrumentation.netty39.server.HttpServerRequestTracingHandler; -import datadog.trace.instrumentation.netty39.server.HttpServerResponseTracingHandler; -import datadog.trace.instrumentation.netty39.server.HttpServerTracingHandler; +import datadog.trace.instrumentation.netty38.client.HttpClientRequestTracingHandler; +import datadog.trace.instrumentation.netty38.client.HttpClientResponseTracingHandler; +import datadog.trace.instrumentation.netty38.client.HttpClientTracingHandler; +import datadog.trace.instrumentation.netty38.server.HttpServerRequestTracingHandler; +import datadog.trace.instrumentation.netty38.server.HttpServerResponseTracingHandler; +import datadog.trace.instrumentation.netty38.server.HttpServerTracingHandler; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -50,7 +50,6 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.ChannelPipeline", - "org.jboss.netty.buffer.EmptyChannelBuffer", // Not in 3.8 "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java similarity index 92% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java index df5fd3e079..75d964529b 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java @@ -1,17 +1,17 @@ -package datadog.trace.instrumentation.netty39.client; +package datadog.trace.instrumentation.netty38.client; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator.DECORATE; -import static datadog.trace.instrumentation.netty39.client.NettyResponseInjectAdapter.SETTER; +import static datadog.trace.instrumentation.netty38.client.NettyHttpClientDecorator.DECORATE; +import static datadog.trace.instrumentation.netty38.client.NettyResponseInjectAdapter.SETTER; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.context.TraceScope; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; import java.net.InetSocketAddress; import lombok.extern.slf4j.Slf4j; import org.jboss.netty.channel.Channel; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientResponseTracingHandler.java similarity index 91% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientResponseTracingHandler.java index ebd5f6fc66..156af2ec6c 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientResponseTracingHandler.java @@ -1,13 +1,13 @@ -package datadog.trace.instrumentation.netty39.client; +package datadog.trace.instrumentation.netty38.client; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopSpan; -import static datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator.DECORATE; +import static datadog.trace.instrumentation.netty38.client.NettyHttpClientDecorator.DECORATE; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientTracingHandler.java similarity index 73% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientTracingHandler.java index 7e0efa27d9..ebc8ebc0fd 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/HttpClientTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientTracingHandler.java @@ -1,8 +1,8 @@ -package datadog.trace.instrumentation.netty39.client; +package datadog.trace.instrumentation.netty38.client; import datadog.trace.bootstrap.ContextStore; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; -import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.util.CombinedSimpleChannelHandler; import org.jboss.netty.channel.Channel; public class HttpClientTracingHandler diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyHttpClientDecorator.java similarity index 96% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyHttpClientDecorator.java index 9ee1c4ea0b..f1f90a206e 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyHttpClientDecorator.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyHttpClientDecorator.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39.client; +package datadog.trace.instrumentation.netty38.client; import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.HOST; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyResponseInjectAdapter.java similarity index 89% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyResponseInjectAdapter.java index 985d7e5d5f..7f4dc69580 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/client/NettyResponseInjectAdapter.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/NettyResponseInjectAdapter.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39.client; +package datadog.trace.instrumentation.netty38.client; import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; import org.jboss.netty.handler.codec.http.HttpHeaders; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java similarity index 91% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java index 33acba335f..67cda84d9b 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java @@ -1,16 +1,16 @@ -package datadog.trace.instrumentation.netty39.server; +package datadog.trace.instrumentation.netty38.server; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator.DECORATE; -import static datadog.trace.instrumentation.netty39.server.NettyRequestExtractAdapter.GETTER; +import static datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator.DECORATE; +import static datadog.trace.instrumentation.netty38.server.NettyRequestExtractAdapter.GETTER; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentSpan.Context; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerResponseTracingHandler.java similarity index 90% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerResponseTracingHandler.java index 3b3104a782..d3b511b2b8 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerResponseTracingHandler.java @@ -1,11 +1,11 @@ -package datadog.trace.instrumentation.netty39.server; +package datadog.trace.instrumentation.netty38.server; -import static datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator.DECORATE; +import static datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator.DECORATE; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.Tags; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerTracingHandler.java similarity index 73% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerTracingHandler.java index c11867d0ea..c4827a1fb7 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/HttpServerTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerTracingHandler.java @@ -1,8 +1,8 @@ -package datadog.trace.instrumentation.netty39.server; +package datadog.trace.instrumentation.netty38.server; import datadog.trace.bootstrap.ContextStore; -import datadog.trace.instrumentation.netty39.ChannelTraceContext; -import datadog.trace.instrumentation.netty39.util.CombinedSimpleChannelHandler; +import datadog.trace.instrumentation.netty38.ChannelTraceContext; +import datadog.trace.instrumentation.netty38.util.CombinedSimpleChannelHandler; import org.jboss.netty.channel.Channel; public class HttpServerTracingHandler diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyHttpServerDecorator.java similarity index 97% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyHttpServerDecorator.java index e51a9c6ea6..b4baa2dbd1 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyHttpServerDecorator.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyHttpServerDecorator.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39.server; +package datadog.trace.instrumentation.netty38.server; import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.HOST; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyRequestExtractAdapter.java similarity index 90% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyRequestExtractAdapter.java index 3834d3209f..39eedcc226 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/server/NettyRequestExtractAdapter.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/NettyRequestExtractAdapter.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39.server; +package datadog.trace.instrumentation.netty38.server; import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; import org.jboss.netty.handler.codec.http.HttpHeaders; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/util/CombinedSimpleChannelHandler.java similarity index 98% rename from dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java rename to dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/util/CombinedSimpleChannelHandler.java index 2823bfe72a..d33442e4b7 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/main/java/datadog/trace/instrumentation/netty39/util/CombinedSimpleChannelHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/util/CombinedSimpleChannelHandler.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.netty39.util; +package datadog.trace.instrumentation.netty38.util; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandlerContext; diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy similarity index 97% rename from dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy rename to dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy index 25ebbe0ac2..a8a5b0d999 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy @@ -4,7 +4,7 @@ import com.ning.http.client.AsyncHttpClientConfig import com.ning.http.client.Response import datadog.trace.agent.test.base.HttpClientTest import datadog.trace.bootstrap.instrumentation.api.Tags -import datadog.trace.instrumentation.netty39.client.NettyHttpClientDecorator +import datadog.trace.instrumentation.netty38.client.NettyHttpClientDecorator import spock.lang.AutoCleanup import spock.lang.Shared diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy similarity index 98% rename from dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy rename to dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy index ab76a536b1..c3d90a0aa6 100644 --- a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/Netty39ServerTest.groovy +++ b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy @@ -1,5 +1,5 @@ import datadog.trace.agent.test.base.HttpServerTest -import datadog.trace.instrumentation.netty39.server.NettyHttpServerDecorator +import datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator import org.jboss.netty.bootstrap.ServerBootstrap import org.jboss.netty.buffer.ChannelBuffer import org.jboss.netty.buffer.ChannelBuffers diff --git a/dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/NettyServerTestInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/netty-3.9/src/test/groovy/NettyServerTestInstrumentation.java rename to dd-java-agent/instrumentation/netty-3.8/src/test/groovy/NettyServerTestInstrumentation.java diff --git a/settings.gradle b/settings.gradle index 0fd80a9c09..e184365078 100644 --- a/settings.gradle +++ b/settings.gradle @@ -112,7 +112,7 @@ include ':dd-java-agent:instrumentation:log4j2' include ':dd-java-agent:instrumentation:mongo' include ':dd-java-agent:instrumentation:mongo:driver-3.1' include ':dd-java-agent:instrumentation:mongo:driver-async-3.3' -include ':dd-java-agent:instrumentation:netty-3.9' +include ':dd-java-agent:instrumentation:netty-3.8' include ':dd-java-agent:instrumentation:netty-4.0' include ':dd-java-agent:instrumentation:netty-4.1' include ':dd-java-agent:instrumentation:okhttp-3' From c8fc300df0e0bdd1e21978e548e2fcb48e433055 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 14:14:41 -0400 Subject: [PATCH 09/15] Not used by aws sdk --- .../netty38/client/HttpClientRequestTracingHandler.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java index 75d964529b..19e8231a88 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java @@ -58,10 +58,7 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand DECORATE.onRequest(span, request); DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.getChannel().getRemoteAddress()); - // AWS calls are often signed, so we can't add headers without breaking the signature. - if (!request.headers().contains("amz-sdk-invocation-id")) { - propagate().inject(span, request.headers(), SETTER); - } + propagate().inject(span, request.headers(), SETTER); channelTraceContext.setClientSpan(span); From 59dffa3d5d6e3f19bde08a1cf5a46d79059c9dbd Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 14:27:47 -0400 Subject: [PATCH 10/15] Minimal change to make muzzle pass --- .../instrumentation/netty38/NettyChannelInstrumentation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index 7619f91e7a..8bf14125a5 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -34,6 +34,7 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.Channel", + "org.jboss.netty.handler.codec.http.DefaultHttpHeaders", // Not in 3.7 "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } From b4be2b18e4aaef5ff65bf386359d69d51d8a56fe Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Fri, 20 Mar 2020 14:57:08 -0400 Subject: [PATCH 11/15] Clarify muzzle specific checks --- .../netty38/ChannelFutureListenerInstrumentation.java | 1 + .../instrumentation/netty38/NettyChannelInstrumentation.java | 2 ++ .../netty38/NettyChannelPipelineInstrumentation.java | 1 + 3 files changed, 4 insertions(+) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index 224d04650a..bb9cb66b62 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -41,6 +41,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.ChannelFutureListener", + // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index 8bf14125a5..12ab34dd1d 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -34,7 +34,9 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.Channel", + // 3.7: cannot find symbol method headers() for type HttpRequest "org.jboss.netty.handler.codec.http.DefaultHttpHeaders", // Not in 3.7 + // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java index dea115942b..be466677ed 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java @@ -50,6 +50,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { // Optimization for expensive typeMatcher. return hasClassesNamed( "org.jboss.netty.channel.ChannelPipeline", + // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 ); } From 17f73b6896714f46b754103880e55dde4b16ff28 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Mon, 23 Mar 2020 10:01:58 -0400 Subject: [PATCH 12/15] Fix small things from review --- .../netty38/ChannelFutureListenerInstrumentation.java | 6 +++--- .../{Netty39ClientTest.groovy => Netty38ClientTest.groovy} | 2 +- .../{Netty39ServerTest.groovy => Netty38ServerTest.groovy} | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename dd-java-agent/instrumentation/netty-3.8/src/test/groovy/{Netty39ClientTest.groovy => Netty38ClientTest.groovy} (98%) rename dd-java-agent/instrumentation/netty-3.8/src/test/groovy/{Netty39ServerTest.groovy => Netty38ServerTest.groovy} (98%) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index bb9cb66b62..b55fd8fb9a 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -4,6 +4,7 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed; import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator.DECORATE; import static java.util.Collections.singletonMap; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -17,7 +18,6 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.context.TraceScope; -import datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator; import java.util.Collections; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -103,8 +103,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { final AgentSpan errorSpan = startSpan("netty.connect").setTag(Tags.COMPONENT, "netty"); try (final AgentScope scope = activateSpan(errorSpan, false)) { - NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause); - NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan); + DECORATE.onError(errorSpan, cause); + DECORATE.beforeFinish(errorSpan); errorSpan.finish(); } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy similarity index 98% rename from dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy rename to dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy index a8a5b0d999..5ff25f501c 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy @@ -15,7 +15,7 @@ import static datadog.trace.agent.test.utils.PortUtils.UNUSABLE_PORT import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace -class Netty39ClientTest extends HttpClientTest { +class Netty38ClientTest extends HttpClientTest { @Shared def clientConfig = new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(TimeUnit.SECONDS.toMillis(10).toInteger()).build() diff --git a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ServerTest.groovy similarity index 98% rename from dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy rename to dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ServerTest.groovy index c3d90a0aa6..e7b0794e0b 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty39ServerTest.groovy +++ b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ServerTest.groovy @@ -14,7 +14,7 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.* import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.* import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1 -class Netty39ServerTest extends HttpServerTest { +class Netty38ServerTest extends HttpServerTest { ChannelPipeline channelPipeline() { ChannelPipeline channelPipeline = new DefaultChannelPipeline() From 5ac54ce10d36f5d6ec60e27793802c7899a69365 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Mon, 23 Mar 2020 10:30:37 -0400 Subject: [PATCH 13/15] Update to support 3.10 also and make muzzle check less brittle --- .../netty-3.8/netty-3.8.gradle | 10 +- .../groovy/Netty38ClientTest.groovy | 106 +++++++++++++++++ .../groovy/Netty38ServerTest.groovy | 111 ++++++++++++++++++ .../NettyServerTestInstrumentation.java | 21 ++++ .../netty38/AbstractNettyAdvice.java | 10 ++ .../ChannelFutureListenerInstrumentation.java | 9 +- .../netty38/NettyChannelInstrumentation.java | 14 +-- .../NettyChannelPipelineInstrumentation.java | 11 +- .../src/test/groovy/Netty38ClientTest.groovy | 5 +- 9 files changed, 268 insertions(+), 29 deletions(-) create mode 100644 dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ClientTest.groovy create mode 100644 dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ServerTest.groovy create mode 100644 dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/NettyServerTestInstrumentation.java create mode 100644 dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/AbstractNettyAdvice.java diff --git a/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle b/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle index d706cd806b..23984df4ba 100644 --- a/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle +++ b/dd-java-agent/instrumentation/netty-3.8/netty-3.8.gradle @@ -10,7 +10,7 @@ muzzle { pass { group = "io.netty" module = "netty" - versions = "[3.8.0.Final,3.10)" + versions = "[3.8.0.Final,4)" assertInverse = true } fail { @@ -23,9 +23,7 @@ muzzle { apply plugin: 'org.unbroken-dome.test-sets' testSets { - latestDepTest { - dirName = 'test' - } + latestDepTest } dependencies { @@ -34,8 +32,8 @@ dependencies { testCompile group: 'io.netty', name: 'netty', version: '3.8.0.Final' testCompile group: 'com.ning', name: 'async-http-client', version: '1.8.0' - latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.9.+' - latestDepTestCompile group: 'com.ning', name: 'async-http-client', version: '1.8.+' + latestDepTestCompile group: 'io.netty', name: 'netty', version: '3.10.+' + latestDepTestCompile group: 'com.ning', name: 'async-http-client', version: '1.9.+' } // We need to force the dependency to the earliest supported version because other libraries declare newer versions. diff --git a/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ClientTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ClientTest.groovy new file mode 100644 index 0000000000..9c26e09b90 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ClientTest.groovy @@ -0,0 +1,106 @@ +import com.ning.http.client.AsyncCompletionHandler +import com.ning.http.client.AsyncHttpClient +import com.ning.http.client.AsyncHttpClientConfig +import com.ning.http.client.Response +import datadog.trace.agent.test.base.HttpClientTest +import datadog.trace.bootstrap.instrumentation.api.Tags +import datadog.trace.instrumentation.netty38.client.NettyHttpClientDecorator +import spock.lang.AutoCleanup +import spock.lang.Shared + +import java.util.concurrent.ExecutionException +import java.util.concurrent.TimeUnit + +import static datadog.trace.agent.test.utils.PortUtils.UNUSABLE_PORT +import static datadog.trace.agent.test.utils.TraceUtils.basicSpan +import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace + +class Netty38ClientTest extends HttpClientTest { + + @Shared + def clientConfig = new AsyncHttpClientConfig.Builder() + .setRequestTimeout(TimeUnit.SECONDS.toMillis(10).toInteger()) + .build() + + @Shared + @AutoCleanup + AsyncHttpClient asyncHttpClient = new AsyncHttpClient(clientConfig) + + @Override + int doRequest(String method, URI uri, Map headers, Closure callback) { + def methodName = "prepare" + method.toLowerCase().capitalize() + def requestBuilder = asyncHttpClient."$methodName"(uri.toString()) + headers.each { requestBuilder.setHeader(it.key, it.value) } + def response = requestBuilder.execute(new AsyncCompletionHandler() { + @Override + Object onCompleted(Response response) throws Exception { + callback?.call() + return response + } + }).get() + blockUntilChildSpansFinished(1) + return response.statusCode + } + + @Override + String component() { + return NettyHttpClientDecorator.DECORATE.component() + } + + @Override + String expectedOperationName() { + return "netty.client.request" + } + + @Override + boolean testRedirects() { + false + } + + @Override + boolean testConnectionFailure() { + false + } + + def "connection error (unopened port)"() { + given: + def uri = new URI("http://localhost:$UNUSABLE_PORT/") + + when: + runUnderTrace("parent") { + doRequest(method, uri) + } + + then: + def ex = thrown(Exception) + def thrownException = ex instanceof ExecutionException ? ex.cause : ex + + and: + assertTraces(1) { + trace(0, 2) { + basicSpan(it, 0, "parent", null, thrownException) + + span(1) { + operationName "netty.connect" + resourceName "netty.connect" + childOf span(0) + errored true + tags { + "$Tags.COMPONENT" "netty" + Class errorClass = ConnectException + try { + errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException') + } catch (ClassNotFoundException e) { + // Older versions use 'java.net.ConnectException' and do not have 'io.netty.channel.AbstractChannel$AnnotatedConnectException' + } + errorTags errorClass, "Connection refused: localhost/127.0.0.1:$UNUSABLE_PORT" + defaultTags() + } + } + } + } + + where: + method = "GET" + } +} diff --git a/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ServerTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ServerTest.groovy new file mode 100644 index 0000000000..e7b0794e0b --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/Netty38ServerTest.groovy @@ -0,0 +1,111 @@ +import datadog.trace.agent.test.base.HttpServerTest +import datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator +import org.jboss.netty.bootstrap.ServerBootstrap +import org.jboss.netty.buffer.ChannelBuffer +import org.jboss.netty.buffer.ChannelBuffers +import org.jboss.netty.channel.* +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory +import org.jboss.netty.handler.codec.http.* +import org.jboss.netty.handler.logging.LoggingHandler +import org.jboss.netty.logging.InternalLogLevel +import org.jboss.netty.util.CharsetUtil + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.* +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.* +import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1 + +class Netty38ServerTest extends HttpServerTest { + + ChannelPipeline channelPipeline() { + ChannelPipeline channelPipeline = new DefaultChannelPipeline() + + channelPipeline.addLast("http-codec", new HttpServerCodec()) + channelPipeline.addLast("controller", new SimpleChannelHandler() { + @Override + void messageReceived(ChannelHandlerContext ctx, MessageEvent msg) throws Exception { + if (msg.getMessage() instanceof HttpRequest) { + def uri = URI.create((msg.getMessage() as HttpRequest).getUri()) + HttpServerTest.ServerEndpoint endpoint = forPath(uri.path) + ctx.sendDownstream controller(endpoint) { + HttpResponse response + ChannelBuffer responseContent = null + switch (endpoint) { + case SUCCESS: + case ERROR: + responseContent = ChannelBuffers.copiedBuffer(endpoint.body, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + case QUERY_PARAM: + responseContent = ChannelBuffers.copiedBuffer(uri.query, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + case REDIRECT: + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.headers().set(LOCATION, endpoint.body) + break + case EXCEPTION: + throw new Exception(endpoint.body) + default: + responseContent = ChannelBuffers.copiedBuffer(NOT_FOUND.body, CharsetUtil.UTF_8) + response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(endpoint.status)) + response.setContent(responseContent) + break + } + response.headers().set(CONTENT_TYPE, "text/plain") + if (responseContent) { + response.headers().set(CONTENT_LENGTH, responseContent.readableBytes()) + } + return new DownstreamMessageEvent( + ctx.getChannel(), + new SucceededChannelFuture(ctx.getChannel()), + response, + ctx.getChannel().getRemoteAddress()) + } + } + } + + @Override + void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent ex) throws Exception { + ChannelBuffer buffer = ChannelBuffers.copiedBuffer(ex.getCause().getMessage(), CharsetUtil.UTF_8) + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR) + response.setContent(buffer) + response.headers().set(CONTENT_TYPE, "text/plain") + response.headers().set(CONTENT_LENGTH, buffer.readableBytes()) + ctx.sendDownstream(new DownstreamMessageEvent( + ctx.getChannel(), + new FailedChannelFuture(ctx.getChannel(), ex.getCause()), + response, + ctx.getChannel().getRemoteAddress())) + } + }) + + return channelPipeline + } + + @Override + Channel startServer(int port) { + ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory()) + bootstrap.setParentHandler(new LoggingHandler(InternalLogLevel.INFO)) + bootstrap.setPipeline(channelPipeline()) + + InetSocketAddress address = new InetSocketAddress(port) + return bootstrap.bind(address) + } + + @Override + void stopServer(Channel server) { + server?.disconnect() + } + + @Override + String component() { + NettyHttpServerDecorator.DECORATE.component() + } + + @Override + String expectedOperationName() { + "netty.request" + } +} diff --git a/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/NettyServerTestInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/NettyServerTestInstrumentation.java new file mode 100644 index 0000000000..9657cea79c --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.8/src/latestDepTest/groovy/NettyServerTestInstrumentation.java @@ -0,0 +1,21 @@ +import static net.bytebuddy.matcher.ElementMatchers.named; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.test.base.HttpServerTestAdvice; +import datadog.trace.agent.tooling.Instrumenter; +import net.bytebuddy.agent.builder.AgentBuilder; + +@AutoService(Instrumenter.class) +public class NettyServerTestInstrumentation implements Instrumenter { + + @Override + public AgentBuilder instrument(final AgentBuilder agentBuilder) { + return agentBuilder + .type(named("org.jboss.netty.handler.codec.http.HttpRequestDecoder")) + .transform( + new AgentBuilder.Transformer.ForAdvice() + .advice( + named("createMessage"), + HttpServerTestAdvice.ServerEntryAdvice.class.getName())); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/AbstractNettyAdvice.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/AbstractNettyAdvice.java new file mode 100644 index 0000000000..97845db559 --- /dev/null +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/AbstractNettyAdvice.java @@ -0,0 +1,10 @@ +package datadog.trace.instrumentation.netty38; + +import org.jboss.netty.handler.codec.http.HttpHeaders; +import org.jboss.netty.handler.codec.http.HttpRequest; + +public class AbstractNettyAdvice { + public static void muzzleCheck(final HttpRequest httpRequest) { + final HttpHeaders headers = httpRequest.headers(); + } +} diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index b55fd8fb9a..8dccca3ad9 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -39,11 +39,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed( - "org.jboss.netty.channel.ChannelFutureListener", - // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader - "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 - ); + return hasClassesNamed("org.jboss.netty.channel.ChannelFutureListener"); } @Override @@ -54,6 +50,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { return new String[] { + packageName + ".AbstractNettyAdvice", packageName + ".ChannelTraceContext", packageName + ".ChannelTraceContext$Factory", packageName + ".server.NettyHttpServerDecorator", @@ -76,7 +73,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); } - public static class OperationCompleteAdvice { + public static class OperationCompleteAdvice extends AbstractNettyAdvice { @Advice.OnMethodEnter public static TraceScope activateScope(@Advice.Argument(0) final ChannelFuture future) { /* diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index 12ab34dd1d..a5252ba1cb 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -32,13 +32,7 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed( - "org.jboss.netty.channel.Channel", - // 3.7: cannot find symbol method headers() for type HttpRequest - "org.jboss.netty.handler.codec.http.DefaultHttpHeaders", // Not in 3.7 - // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader - "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 - ); + return hasClassesNamed("org.jboss.netty.channel.Channel"); } @Override @@ -49,7 +43,9 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { return new String[] { - packageName + ".ChannelTraceContext", packageName + ".ChannelTraceContext$Factory" + packageName + ".AbstractNettyAdvice", + packageName + ".ChannelTraceContext", + packageName + ".ChannelTraceContext$Factory" }; } @@ -70,7 +66,7 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); } - public static class ChannelConnectAdvice { + public static class ChannelConnectAdvice extends AbstractNettyAdvice { @Advice.OnMethodEnter public static void addConnectContinuation(@Advice.This final Channel channel) { final TraceScope scope = activeScope(); diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java index be466677ed..2ceafcbf86 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java @@ -48,11 +48,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { @Override public ElementMatcher classLoaderMatcher() { // Optimization for expensive typeMatcher. - return hasClassesNamed( - "org.jboss.netty.channel.ChannelPipeline", - // 3.10: NoSuchMethodError: org.jboss.netty.handler.codec.http.HttpRequest.setHeader - "org.jboss.netty.channel.StaticChannelPipeline" // Not in 3.10 - ); + return hasClassesNamed("org.jboss.netty.channel.ChannelPipeline"); } @Override @@ -63,6 +59,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { @Override public String[] helperClassNames() { return new String[] { + packageName + ".AbstractNettyAdvice", packageName + ".ChannelTraceContext", packageName + ".ChannelTraceContext$Factory", NettyChannelPipelineInstrumentation.class.getName() + "$ChannelPipelineAdviceUtil", @@ -150,7 +147,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { } } - public static class ChannelPipelineAdd2ArgsAdvice { + public static class ChannelPipelineAdd2ArgsAdvice extends AbstractNettyAdvice { @Advice.OnMethodEnter public static int checkDepth( @Advice.This final ChannelPipeline pipeline, @@ -180,7 +177,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { } } - public static class ChannelPipelineAdd3ArgsAdvice { + public static class ChannelPipelineAdd3ArgsAdvice extends AbstractNettyAdvice { @Advice.OnMethodEnter public static int checkDepth( @Advice.This final ChannelPipeline pipeline, diff --git a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy index 5ff25f501c..c56d227845 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-3.8/src/test/groovy/Netty38ClientTest.groovy @@ -18,7 +18,10 @@ import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace class Netty38ClientTest extends HttpClientTest { @Shared - def clientConfig = new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(TimeUnit.SECONDS.toMillis(10).toInteger()).build() + def clientConfig = new AsyncHttpClientConfig.Builder() + .setRequestTimeoutInMs(TimeUnit.SECONDS.toMillis(10).toInteger()) + .build() + @Shared @AutoCleanup AsyncHttpClient asyncHttpClient = new AsyncHttpClient(clientConfig) From d4a4c5619c7bc303c73d701b023638b7a51a3913 Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Mon, 23 Mar 2020 14:03:00 -0400 Subject: [PATCH 14/15] Less class loads --- .../netty38/ChannelFutureListenerInstrumentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index 8dccca3ad9..9b997c1fc4 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -70,7 +70,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { @Override public Map contextStore() { return Collections.singletonMap( - "org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName()); + "org.jboss.netty.channel.Channel", packageName + ".ChannelTraceContext"); } public static class OperationCompleteAdvice extends AbstractNettyAdvice { From 5aa1800bec90358ec10be6b3869dd549409c8dac Mon Sep 17 00:00:00 2001 From: Brian Devins-Suresh Date: Mon, 23 Mar 2020 14:44:11 -0400 Subject: [PATCH 15/15] Get rid of half baked map methods. Close parentScope in a finally block (+forward port) --- .../ChannelFutureListenerInstrumentation.java | 3 ++- .../netty38/ChannelTraceContext.java | 16 ---------------- .../netty38/NettyChannelInstrumentation.java | 9 ++++++--- .../NettyChannelPipelineInstrumentation.java | 2 -- .../client/HttpClientRequestTracingHandler.java | 8 ++++---- .../client/HttpClientRequestTracingHandler.java | 8 ++++---- .../client/HttpClientRequestTracingHandler.java | 8 ++++---- 7 files changed, 20 insertions(+), 34 deletions(-) diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java index 9b997c1fc4..1e25fd4a7b 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelFutureListenerInstrumentation.java @@ -92,7 +92,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { final TraceScope.Continuation continuation = contextStore .putIfAbsent(future.getChannel(), ChannelTraceContext.Factory.INSTANCE) - .getConnectionContinuationAndRemove(); + .getConnectionContinuation(); + contextStore.get(future.getChannel()).setConnectionContinuation(null); if (continuation == null) { return null; } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java index 1bba8ba74a..812ad71f6f 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/ChannelTraceContext.java @@ -20,20 +20,4 @@ public class ChannelTraceContext { AgentSpan serverSpan; AgentSpan clientSpan; AgentSpan clientParentSpan; - - public boolean compareAndSet( - final TraceScope.Continuation compareTo, final TraceScope.Continuation setTo) { - if (connectionContinuation == compareTo) { - connectionContinuation = setTo; - return true; - } else { - return false; - } - } - - public TraceScope.Continuation getConnectionContinuationAndRemove() { - final TraceScope.Continuation current = connectionContinuation; - connectionContinuation = null; - return current; - } } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index a5252ba1cb..d43eb15ad9 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -76,10 +76,13 @@ public class NettyChannelInstrumentation extends Instrumenter.Default { final ContextStore contextStore = InstrumentationContext.get(Channel.class, ChannelTraceContext.class); - if (!contextStore - .putIfAbsent(channel, ChannelTraceContext.Factory.INSTANCE) - .compareAndSet(null, continuation)) { + if (contextStore + .putIfAbsent(channel, ChannelTraceContext.Factory.INSTANCE) + .getConnectionContinuation() + != null) { continuation.close(); + } else { + contextStore.get(channel).setConnectionContinuation(continuation); } } } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java index 2ceafcbf86..d592fb9264 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelPipelineInstrumentation.java @@ -139,8 +139,6 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { HttpClientResponseTracingHandler.class.getName(), new HttpClientResponseTracingHandler(contextStore)); } - } catch (final IllegalArgumentException e) { - // Prevented adding duplicate handlers. } finally { CallDepthThreadLocalMap.reset(ChannelPipeline.class); } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java index 19e8231a88..df488fbef6 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/client/HttpClientRequestTracingHandler.java @@ -70,10 +70,10 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand span.finish(); throw throwable; } - } - - if (null != parentScope) { - parentScope.close(); + } finally { + if (parentScope != null) { + parentScope.close(); + } } } } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java index cf2a5cf9ad..a34c269521 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java @@ -60,10 +60,10 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt span.finish(); throw throwable; } - } - - if (null != parentScope) { - parentScope.close(); + } finally { + if (null != parentScope) { + parentScope.close(); + } } } } diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java index 86b8294486..38ba4d9cbd 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java @@ -60,10 +60,10 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt span.finish(); throw throwable; } - } - - if (null != parentScope) { - parentScope.close(); + } finally { + if (null != parentScope) { + parentScope.close(); + } } } }