Fix span relationships and other review issues.
MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/muzzle/ReferenceCreator.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/muzzle/ReferenceCreator.java
@@ -46,9 +46,11 @@ public class ReferenceCreator extends ClassVisitor {
* @param loader Classloader used to read class bytes.
* @param startFromMethodBodies if true only create refs from method bodies.
* @return Map of [referenceClassName -> Reference]
+ * @throws IllegalStateException if class is not found or unable to be loaded.
*/
private static Map<String, Reference> createReferencesFrom(
- final String entryPointClassName, final ClassLoader loader, boolean startFromMethodBodies) {
+ final String entryPointClassName, final ClassLoader loader, boolean startFromMethodBodies)
+ throws IllegalStateException {
final Set<String> visitedSources = new HashSet<>();
final Map<String, Reference> references = new HashMap<>();

MODIFY
dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java
dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java
package datadog.trace.instrumentation.netty40;
import datadog.trace.context.TraceScope;
+import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
import io.netty.util.AttributeKey;
import io.opentracing.Span;
@@ -14,5 +15,5 @@ public class AttributeKeys {
new AttributeKey<>(HttpServerTracingHandler.class.getName() + ".span");
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
- new AttributeKey<>(HttpServerTracingHandler.class.getName() + ".span");
+ new AttributeKey<>(HttpClientTracingHandler.class.getName() + ".span");
}

MODIFY
dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java
dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java
@@ -43,6 +43,14 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
return new String[] {
packageName + ".AttributeKeys",
"datadog.trace.agent.decorator.BaseDecorator",
+ // client helpers
+ "datadog.trace.agent.decorator.ClientDecorator",
+ "datadog.trace.agent.decorator.HttpClientDecorator",
+ packageName + ".client.NettyHttpClientDecorator",
+ packageName + ".client.NettyResponseInjectAdapter",
+ packageName + ".client.HttpClientRequestTracingHandler",
+ packageName + ".client.HttpClientResponseTracingHandler",
+ packageName + ".client.HttpClientTracingHandler",
// server helpers
"datadog.trace.agent.decorator.ServerDecorator",
"datadog.trace.agent.decorator.HttpServerDecorator",

MODIFY
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/AttributeKeys.java
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/AttributeKeys.java
package datadog.trace.instrumentation.netty41;
import datadog.trace.context.TraceScope;
+import datadog.trace.instrumentation.netty41.client.HttpClientTracingHandler;
import datadog.trace.instrumentation.netty41.server.HttpServerTracingHandler;
import io.netty.util.AttributeKey;
import io.opentracing.Span;
@@ -18,5 +19,5 @@ public class AttributeKeys {
AttributeKey.valueOf(HttpServerTracingHandler.class.getName() + ".span");
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
- AttributeKey.valueOf(HttpServerTracingHandler.class.getName() + ".span");
+ AttributeKey.valueOf(HttpClientTracingHandler.class.getName() + ".span");
}

MODIFY
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java
@@ -43,6 +43,14 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
return new String[] {
packageName + ".AttributeKeys",
"datadog.trace.agent.decorator.BaseDecorator",
+ // client helpers
+ "datadog.trace.agent.decorator.ClientDecorator",
+ "datadog.trace.agent.decorator.HttpClientDecorator",
+ packageName + ".client.NettyHttpClientDecorator",
+ packageName + ".client.NettyResponseInjectAdapter",
+ packageName + ".client.HttpClientRequestTracingHandler",
+ packageName + ".client.HttpClientResponseTracingHandler",
+ packageName + ".client.HttpClientTracingHandler",
// server helpers
"datadog.trace.agent.decorator.ServerDecorator",
"datadog.trace.agent.decorator.HttpServerDecorator",

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/latestDepTest/groovy/RatpackTest.groovy
dd-java-agent/instrumentation/ratpack-1.4/src/latestDepTest/groovy/RatpackTest.groovy
@@ -19,18 +19,18 @@ import ratpack.http.HttpUrlBuilder
import ratpack.http.client.HttpClient
import ratpack.path.PathBinding
import ratpack.test.exec.ExecHarness
-import spock.lang.Retry
import java.util.concurrent.CountDownLatch
+import java.util.regex.Pattern
+import static datadog.trace.agent.test.server.http.TestHttpServer.distributedRequestTrace
+import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static datadog.trace.agent.test.utils.PortUtils.UNUSABLE_PORT
-@Retry
class RatpackTest extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
-
def "test path call"() {
setup:
def app = GroovyEmbeddedApp.ratpack {
@@ -193,7 +193,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
- errorTags(ArithmeticException, "Division undefined")
+ errorTags(ArithmeticException, Pattern.compile("Division( is)? undefined"))
defaultTags()
}
}
@@ -210,7 +210,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 500
"$Tags.HTTP_URL.key" "/"
- errorTags(HandlerException, "java.lang.ArithmeticException: Division undefined")
+ errorTags(HandlerException, Pattern.compile("java.lang.ArithmeticException: Division( is)? undefined"))
defaultTags()
}
}
@@ -258,7 +258,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
- errorTags(ArithmeticException, "Division undefined")
+ errorTags(ArithmeticException, Pattern.compile("Division( is)? undefined"))
defaultTags()
}
}
@@ -321,7 +321,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
- errorTags(ArithmeticException, "Division undefined")
+ errorTags(ArithmeticException, Pattern.compile("Division( is)? undefined"))
defaultTags()
}
}
@@ -349,13 +349,16 @@ class RatpackTest extends AgentTestRunner {
def "test path call using ratpack http client"() {
setup:
- def external = GroovyEmbeddedApp.ratpack {
+ // Use jetty based server to avoid confusion.
+ def external = httpServer {
handlers {
get("nested") {
- context.render("succ")
+ handleDistributedRequest()
+ response.send("succ")
}
get("nested2") {
- context.render("ess")
+ handleDistributedRequest()
+ response.send("ess")
}
}
}
@@ -392,82 +395,9 @@ class RatpackTest extends AgentTestRunner {
// 2nd is nested2 from the external server (the result of the 2nd internal http client call)
// 1st is nested from the external server (the result of the 1st internal http client call)
assertTraces(3) {
- // simulated external system, first call
- trace(0, 2) {
- span(0) {
- resourceName "GET /nested"
- serviceName "unnamed-java-app"
- operationName "netty.request"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(trace(2).get(3))
- errored false
- tags {
- "$Tags.COMPONENT.key" "netty"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested"
- "$Tags.PEER_HOSTNAME.key" "$app.address.host"
- "$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
- "$Tags.PEER_PORT.key" Integer
- defaultTags(true)
- }
- }
- span(1) {
- resourceName "GET /nested"
- serviceName "unnamed-java-app"
- operationName "ratpack.handler"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(span(0))
- errored false
- tags {
- "$Tags.COMPONENT.key" "ratpack"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "/nested"
- defaultTags()
- }
- }
- }
-// // simulated external system, second call
- trace(1, 2) {
- span(0) {
- resourceName "GET /nested2"
- serviceName "unnamed-java-app"
- operationName "netty.request"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(trace(2).get(2))
- errored false
- tags {
- "$Tags.COMPONENT.key" "netty"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested2"
- "$Tags.PEER_HOSTNAME.key" "$app.address.host"
- "$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
- "$Tags.PEER_PORT.key" Integer
- defaultTags(true)
- }
- }
- span(1) {
- resourceName "GET /nested2"
- serviceName "unnamed-java-app"
- operationName "ratpack.handler"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(span(0))
- errored false
- tags {
- "$Tags.COMPONENT.key" "ratpack"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "/nested2"
- defaultTags()
- }
- }
- }
+ distributedRequestTrace(it, 0, trace(2).get(3))
+ distributedRequestTrace(it, 1, trace(2).get(2))
+
trace(2, 4) {
// main app span that processed the request from OKHTTP request
span(0) {
@@ -518,7 +448,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested2"
+ "$Tags.HTTP_URL.key" "${external.address}/nested2"
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
@@ -531,14 +461,14 @@ class RatpackTest extends AgentTestRunner {
serviceName "unnamed-java-app"
operationName "netty.client.request"
spanType DDSpanTypes.HTTP_CLIENT
- childOf(span(0))
+ childOf(span(1))
errored false
tags {
"$Tags.COMPONENT.key" "netty-client"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested"
+ "$Tags.HTTP_URL.key" "${external.address}/nested"
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
@@ -617,10 +547,7 @@ class RatpackTest extends AgentTestRunner {
span(2) {
operationName "netty.connect"
resourceName "netty.connect"
- // Notice the span is a child of the netty span.
- // I don't think we can easily get it rooted under the ratpack span
- // since the "parent" is stored on the channel.
- childOf(span(0))
+ childOf(span(1))
errored true
tags {
"$Tags.COMPONENT.key" "netty"

ADD
dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/ExecStreamInstrumentation.java
+package datadog.trace.instrumentation.ratpack;
+
+import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
+import static net.bytebuddy.matcher.ElementMatchers.isInterface;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.not;
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+
+import com.google.auto.service.AutoService;
+import datadog.trace.agent.tooling.Instrumenter;
+import datadog.trace.context.TraceScope;
+import io.opentracing.Scope;
+import io.opentracing.util.GlobalTracer;
+import java.util.Collections;
+import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.asm.Advice;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import ratpack.exec.internal.Continuation;
+import ratpack.func.Action;
+import ratpack.path.PathBinding;
+
+@AutoService(Instrumenter.class)
+public final class ExecStreamInstrumentation extends Instrumenter.Default {
+
+ public ExecStreamInstrumentation() {
+ super("ratpack");
+ }
+
+ @Override
+ public ElementMatcher<? super TypeDescription> typeMatcher() {
+ return not(isInterface())
+ .and(safeHasSuperType(named("ratpack.exec.internal.DefaultExecution")));
+ }
+
+ // ratpack.exec.internal.DefaultExecution.delimit
+ @Override
+ public String[] helperClassNames() {
+ return new String[] {
+ packageName + ".ExecStreamInstrumentation$ActionWrapper",
+ };
+ }
+
+ @Override
+ public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
+ return Collections.singletonMap(
+ named("delimit")
+ .or(named("delimitStream"))
+ .and(takesArgument(0, named("ratpack.func.Action")))
+ .and(takesArgument(1, named("ratpack.func.Action"))),
+ WrapActionAdvice.class.getName());
+ }
+
+ public static class WrapActionAdvice {
+
+ @Advice.OnMethodEnter(suppress = Throwable.class)
+ public static void wrap(
+ @Advice.Argument(value = 0, readOnly = false) Action<Throwable> onError,
+ @Advice.Argument(value = 1, readOnly = false) Action<Continuation> segment) {
+ final Scope scope = GlobalTracer.get().scopeManager().active();
+ if (scope instanceof TraceScope) {
+ final TraceScope.Continuation continuation = ((TraceScope) scope).capture();
+ onError = ActionWrapper.wrapIfNeeded(onError, continuation);
+ segment = ActionWrapper.wrapIfNeeded(segment, continuation);
+ }
+ }
+
+ public void muzzleCheck(final PathBinding binding) {
+ // This was added in 1.4. Added here to ensure consistency with other instrumentation.
+ binding.getDescription();
+ }
+ }
+
+ @Slf4j
+ public static class ActionWrapper<T> implements Action<T> {
+ private final Action<T> delegate;
+ private final TraceScope.Continuation traceContinuation;
+
+ private ActionWrapper(
+ final Action<T> delegate, final TraceScope.Continuation traceContinuation) {
+ this.delegate = delegate;
+ this.traceContinuation = traceContinuation;
+ }
+
+ @Override
+ public void execute(final T subject) throws Exception {
+ if (traceContinuation != null) {
+ try (final TraceScope scope = traceContinuation.activate()) {
+ scope.setAsyncPropagation(true);
+ delegate.execute(subject);
+ }
+ } else {
+ delegate.execute(subject);
+ }
+ }
+
+ public static <T> Action<T> wrapIfNeeded(
+ final Action<T> delegate, final TraceScope.Continuation traceContinuation) {
+ if (delegate instanceof ActionWrapper) {
+ return delegate;
+ }
+ log.debug("Wrapping action task {}", delegate);
+ return new ActionWrapper<>(delegate, traceContinuation);
+ }
+ }
+}

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/ServerRegistryInstrumentation.java
dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/ServerRegistryInstrumentation.java
@@ -39,6 +39,6 @@ public class ServerRegistryInstrumentation extends Instrumenter.Default {
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
- packageName + ".RatpackServerRegistryAdvice");
+ packageName + ".ServerRegistryAdvice");
}
}

RENAME
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/RatpackServerRegistryAdvice.java
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/ServerRegistryAdvice.java
@@ -4,11 +4,11 @@ import net.bytebuddy.asm.Advice;
import ratpack.handling.HandlerDecorator;
import ratpack.registry.Registry;
-public class RatpackServerRegistryAdvice {
+public class ServerRegistryAdvice {
@Advice.OnMethodExit(suppress = Throwable.class)
public static void injectTracing(@Advice.Return(readOnly = false) Registry registry) {
registry =
registry.join(
- Registry.builder().add(HandlerDecorator.prepend(new TracingHandler())).build());
+ Registry.builder().add(HandlerDecorator.prepend(TracingHandler.INSTANCE)).build());
}
}

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/TracingHandler.java
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/TracingHandler.java
@@ -18,6 +18,8 @@ import ratpack.http.Request;
* that the span is closed when the response is sent
*/
public final class TracingHandler implements Handler {
+ public static Handler INSTANCE = new TracingHandler();
+
/**
* This constant is copied over from datadog.trace.instrumentation.netty41.AttributeKeys. The key
* string must be kept consistent.
@@ -64,7 +66,8 @@ public final class TracingHandler implements Handler {
} catch (final Throwable e) {
DECORATE.onError(ratpackSpan, e);
DECORATE.beforeFinish(ratpackSpan);
- ratpackSpan.finish(); // Do we need to finish?
+ // finish since the callback probably didn't get added.
+ ratpackSpan.finish();
throw e;
}
}

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/test/groovy/RatpackTest.groovy
dd-java-agent/instrumentation/ratpack-1.4/src/test/groovy/RatpackTest.groovy
@@ -18,19 +18,18 @@ import ratpack.http.HttpUrlBuilder
import ratpack.http.client.HttpClient
import ratpack.path.PathBinding
import ratpack.test.exec.ExecHarness
-import spock.lang.Retry
import java.util.concurrent.CountDownLatch
import java.util.regex.Pattern
+import static datadog.trace.agent.test.server.http.TestHttpServer.distributedRequestTrace
+import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static datadog.trace.agent.test.utils.PortUtils.UNUSABLE_PORT
-@Retry
class RatpackTest extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
-
def "test path call"() {
setup:
def app = GroovyEmbeddedApp.ratpack {
@@ -349,13 +348,16 @@ class RatpackTest extends AgentTestRunner {
def "test path call using ratpack http client"() {
setup:
- def external = GroovyEmbeddedApp.ratpack {
+ // Use jetty based server to avoid confusion.
+ def external = httpServer {
handlers {
get("nested") {
- context.render("succ")
+ handleDistributedRequest()
+ response.send("succ")
}
get("nested2") {
- context.render("ess")
+ handleDistributedRequest()
+ response.send("ess")
}
}
}
@@ -392,82 +394,9 @@ class RatpackTest extends AgentTestRunner {
// 2nd is nested2 from the external server (the result of the 2nd internal http client call)
// 1st is nested from the external server (the result of the 1st internal http client call)
assertTraces(3) {
- // simulated external system, first call
- trace(0, 2) {
- span(0) {
- resourceName "GET /nested"
- serviceName "unnamed-java-app"
- operationName "netty.request"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(trace(2).get(3))
- errored false
- tags {
- "$Tags.COMPONENT.key" "netty"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested"
- "$Tags.PEER_HOSTNAME.key" "$app.address.host"
- "$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
- "$Tags.PEER_PORT.key" Integer
- defaultTags(true)
- }
- }
- span(1) {
- resourceName "GET /nested"
- serviceName "unnamed-java-app"
- operationName "ratpack.handler"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(span(0))
- errored false
- tags {
- "$Tags.COMPONENT.key" "ratpack"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "/nested"
- defaultTags()
- }
- }
- }
-// // simulated external system, second call
- trace(1, 2) {
- span(0) {
- resourceName "GET /nested2"
- serviceName "unnamed-java-app"
- operationName "netty.request"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(trace(2).get(2))
- errored false
- tags {
- "$Tags.COMPONENT.key" "netty"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested2"
- "$Tags.PEER_HOSTNAME.key" "$app.address.host"
- "$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
- "$Tags.PEER_PORT.key" Integer
- defaultTags(true)
- }
- }
- span(1) {
- resourceName "GET /nested2"
- serviceName "unnamed-java-app"
- operationName "ratpack.handler"
- spanType DDSpanTypes.HTTP_SERVER
- childOf(span(0))
- errored false
- tags {
- "$Tags.COMPONENT.key" "ratpack"
- "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
- "$Tags.HTTP_METHOD.key" "GET"
- "$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "/nested2"
- defaultTags()
- }
- }
- }
+ distributedRequestTrace(it, 0, trace(2).get(3))
+ distributedRequestTrace(it, 1, trace(2).get(2))
+
trace(2, 4) {
// main app span that processed the request from OKHTTP request
span(0) {
@@ -518,7 +447,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested2"
+ "$Tags.HTTP_URL.key" "${external.address}/nested2"
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
@@ -531,14 +460,14 @@ class RatpackTest extends AgentTestRunner {
serviceName "unnamed-java-app"
operationName "netty.client.request"
spanType DDSpanTypes.HTTP_CLIENT
- childOf(span(0))
+ childOf(span(1))
errored false
tags {
"$Tags.COMPONENT.key" "netty-client"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200
- "$Tags.HTTP_URL.key" "${external.address}nested"
+ "$Tags.HTTP_URL.key" "${external.address}/nested"
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
@@ -593,7 +522,7 @@ class RatpackTest extends AgentTestRunner {
"$Tags.PEER_HOSTNAME.key" "$app.address.host"
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
"$Tags.PEER_PORT.key" Integer
- errorTags(ConnectException, String)
+ "$Tags.ERROR.key" true
defaultTags()
}
}
@@ -610,17 +539,14 @@ class RatpackTest extends AgentTestRunner {
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 500
"$Tags.HTTP_URL.key" "/"
- "$Tags.ERROR.key" true
+ errorTags(ConnectException, String)
defaultTags()
}
}
span(2) {
operationName "netty.connect"
resourceName "netty.connect"
- // Notice the span is a child of the netty span.
- // I don't think we can easily get it rooted under the ratpack span
- // since the "parent" is stored on the channel.
- childOf(span(0))
+ childOf(span(1))
errored true
tags {
"$Tags.COMPONENT.key" "netty"

MODIFY
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/server/http/TestHttpServer.groovy
@@ -298,6 +298,7 @@ class TestHttpServer implements AutoCloseable {
assert body != null
send()
+ resp.setContentLength(body.bytes.length)
resp.writer.print(body)
}
}

MODIFY
dd-trace-api/src/main/java/datadog/trace/context/TraceScope.java
dd-trace-api/src/main/java/datadog/trace/context/TraceScope.java
package datadog.trace.context;
+import java.io.Closeable;
+
/** An object when can propagate a datadog trace across multiple threads. */
-public interface TraceScope {
+public interface TraceScope extends Closeable {
/**
* Prevent the trace attached to this TraceScope from reporting until the returned Continuation
* finishes.
@@ -11,6 +13,7 @@ public interface TraceScope {
Continuation capture();
/** Close the activated context and allow any underlying spans to finish. */
+ @Override
void close();
/** If true, this context will propagate across async boundaries. */

Fix span relationships and other review issues.