Address comments and add onClose callback on context to close scope.
DELETE
dd-java-agent/benchmark-integration/play-perftest/jetty-perftest.gradle
-dependencies {
- compile project(':dd-trace-api')
- compile project(':dd-java-agent:benchmark-integration')
- compile deps.opentracing
-
- compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.1.v20170120'
- compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.4.1.v20170120'
-}
-
-jar {
- manifest {
- attributes(
- "Main-Class": "datadog.perftest.jetty.JettyPerftest"
- )
- }
-}

DELETE
dd-java-agent/benchmark-integration/play-perftest/src/main/java/datadog/perftest/Worker.java
-package datadog.perftest;
-
-import datadog.trace.api.Trace;
-import io.opentracing.Span;
-import io.opentracing.util.GlobalTracer;
-import java.util.concurrent.TimeUnit;
-
-public class Worker {
-
- @Trace
- /** Simulate work for the give number of milliseconds. */
- public static void doWork(final long workTimeMS) {
- final Span span = GlobalTracer.get().activeSpan();
- if (span != null) {
- span.setTag("work-time", workTimeMS);
- span.setTag("info", "interesting stuff");
- span.setTag("additionalInfo", "interesting stuff");
- }
-
- final long doneTimestamp = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(workTimeMS);
- while (System.nanoTime() < doneTimestamp) {
- // busy-wait to simulate work
- }
- }
-}

DELETE
dd-java-agent/benchmark-integration/play-perftest/src/main/java/datadog/perftest/jetty/JettyPerftest.java
-package datadog.perftest.jetty;
-
-import datadog.perftest.Worker;
-import datadog.trace.api.Trace;
-import io.opentracing.Span;
-import io.opentracing.util.GlobalTracer;
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-
-public class JettyPerftest {
- private static final int PORT = 8080;
- private static final String PATH = "/work";
- private static final Server jettyServer = new Server(PORT);
- private static final ServletContextHandler servletContext = new ServletContextHandler();
-
- public static void main(final String[] args) throws Exception {
- servletContext.addServlet(PerfServlet.class, PATH);
- jettyServer.setHandler(servletContext);
- jettyServer.start();
-
- Runtime.getRuntime()
- .addShutdownHook(
- new Thread() {
- @Override
- public void run() {
- try {
- jettyServer.stop();
- jettyServer.destroy();
- } catch (final Exception e) {
- throw new IllegalStateException(e);
- }
- }
- });
- }
-
- @WebServlet
- public static class PerfServlet extends HttpServlet {
- @Override
- protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException {
- if (request.getParameter("error") != null) {
- throw new RuntimeException("some sync error");
- }
- final String workVal = request.getParameter("workTimeMS");
- long workTimeMS = 0l;
- if (null != workVal) {
- workTimeMS = Long.parseLong(workVal);
- }
- scheduleWork(workTimeMS);
- response.getWriter().print("Did " + workTimeMS + "ms of work.");
- }
-
- @Trace
- private void scheduleWork(final long workTimeMS) {
- final Span span = GlobalTracer.get().activeSpan();
- if (span != null) {
- span.setTag("work-time", workTimeMS);
- span.setTag("info", "interesting stuff");
- span.setTag("additionalInfo", "interesting stuff");
- }
- if (workTimeMS > 0) {
- Worker.doWork(workTimeMS);
- }
- }
- }
-}

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/impl/RatpackServerAdvice.java
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/impl/RatpackServerAdvice.java
package datadog.trace.instrumentation.ratpack.impl;
import io.opentracing.Scope;
-import io.opentracing.ScopeManager;
import io.opentracing.util.GlobalTracer;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.asm.Advice;
@@ -18,10 +17,7 @@ public class RatpackServerAdvice {
public static void injectTracing(@Advice.Return(readOnly = false) Registry registry) {
registry =
registry.join(
- Registry.builder()
- .add(ScopeManager.class, GlobalTracer.get().scopeManager())
- .add(HandlerDecorator.prepend(new TracingHandler()))
- .build());
+ Registry.builder().add(HandlerDecorator.prepend(new TracingHandler())).build());
}
}

MODIFY
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/impl/TracingHandler.java
dd-java-agent/instrumentation/ratpack-1.4/src/main/java8/datadog/trace/instrumentation/ratpack/impl/TracingHandler.java
@@ -36,29 +36,41 @@ public final class TracingHandler implements Handler {
.withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_SERVER)
.withTag(Tags.HTTP_METHOD.getKey(), request.getMethod().getName())
.withTag(Tags.HTTP_URL.getKey(), request.getUri())
- .startActive(true);
+ .startActive(false);
if (scope instanceof TraceScope) {
((TraceScope) scope).setAsyncPropagation(true);
}
+ final Span rootSpan = scope.span();
+
ctx.getResponse()
.beforeSend(
response -> {
- if (scope instanceof TraceScope) {
- ((TraceScope) scope).setAsyncPropagation(false);
+ final Scope responseScope = GlobalTracer.get().scopeManager().active();
+
+ if (responseScope instanceof TraceScope) {
+ ((TraceScope) responseScope).setAsyncPropagation(false);
}
- final Span span = scope.span();
- span.setTag(DDTags.RESOURCE_NAME, getResourceName(ctx));
+
+ rootSpan.setTag(DDTags.RESOURCE_NAME, getResourceName(ctx));
final Status status = response.getStatus();
if (status != null) {
if (status.is5xx()) {
- Tags.ERROR.set(span, true);
+ Tags.ERROR.set(rootSpan, true);
}
- Tags.HTTP_STATUS.set(span, status.getCode());
+ Tags.HTTP_STATUS.set(rootSpan, status.getCode());
}
- scope.close();
+ rootSpan.finish();
+ });
+
+ ctx.onClose(
+ requestOutcome -> {
+ final Scope activeScope = GlobalTracer.get().scopeManager().active();
+ if (activeScope != null) {
+ activeScope.close();
+ }
});
ctx.next();

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
@@ -46,25 +46,6 @@ class RatpackTest extends AgentTestRunner {
resp.code() == 200
resp.body.string() == "success"
-<<<<<<< HEAD
- TEST_WRITER.size() == 1
- def trace = TEST_WRITER.firstTrace()
- trace.size() == 1
- def span = trace[0]
-
- span.context().serviceName == "unnamed-java-app"
- span.context().operationName == "ratpack.handler"
- span.context().resourceName == "GET /"
- span.context().tags["component"] == "ratpack"
- span.context().spanType == DDSpanTypes.HTTP_SERVER
- !span.context().getErrorFlag()
- span.context().tags["http.url"] == "/"
- span.context().tags["http.method"] == "GET"
- span.context().tags["span.kind"] == "server"
- span.context().tags["http.status_code"] == 200
- span.context().tags["thread.name"] != null
- span.context().tags["thread.id"] != null
-=======
assertTraces(1) {
trace(0, 1) {
span(0) {
@@ -75,7 +56,7 @@ class RatpackTest extends AgentTestRunner {
parent()
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -86,7 +67,6 @@ class RatpackTest extends AgentTestRunner {
}
}
}
->>>>>>> 1bfa7e47... Refactor Ratpack
}
def "test path with bindings call"() {
@@ -112,25 +92,6 @@ class RatpackTest extends AgentTestRunner {
resp.code() == 200
resp.body.string() == ":foo/:bar?/baz"
-<<<<<<< HEAD
- TEST_WRITER.size() == 1
- def trace = TEST_WRITER.firstTrace()
- trace.size() == 1
- def span = trace[0]
-
- span.context().serviceName == "unnamed-java-app"
- span.context().operationName == "ratpack.handler"
- span.context().resourceName == "GET /:foo/:bar?/baz"
- span.context().tags["component"] == "ratpack"
- span.context().spanType == DDSpanTypes.HTTP_SERVER
- !span.context().getErrorFlag()
- span.context().tags["http.url"] == "/a/b/baz"
- span.context().tags["http.method"] == "GET"
- span.context().tags["span.kind"] == "server"
- span.context().tags["http.status_code"] == 200
- span.context().tags["thread.name"] != null
- span.context().tags["thread.id"] != null
-=======
assertTraces(1) {
trace(0, 1) {
span(0) {
@@ -141,7 +102,7 @@ class RatpackTest extends AgentTestRunner {
parent()
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -152,7 +113,6 @@ class RatpackTest extends AgentTestRunner {
}
}
}
->>>>>>> 1bfa7e47... Refactor Ratpack
}
def "test error response"() {
@@ -175,25 +135,6 @@ class RatpackTest extends AgentTestRunner {
then:
resp.code() == 500
-<<<<<<< HEAD
- TEST_WRITER.size() == 1
- def trace = TEST_WRITER.firstTrace()
- trace.size() == 1
- def span = trace[0]
-
- span.context().getErrorFlag()
- span.context().serviceName == "unnamed-java-app"
- span.context().operationName == "ratpack.handler"
- span.context().resourceName == "GET /"
- span.context().tags["component"] == "ratpack"
- span.context().spanType == DDSpanTypes.HTTP_SERVER
- span.context().tags["http.url"] == "/"
- span.context().tags["http.method"] == "GET"
- span.context().tags["span.kind"] == "server"
- span.context().tags["http.status_code"] == 500
- span.context().tags["thread.name"] != null
- span.context().tags["thread.id"] != null
-=======
assertTraces(1) {
trace(0, 1) {
span(0) {
@@ -204,7 +145,7 @@ class RatpackTest extends AgentTestRunner {
parent()
errored true
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -217,7 +158,6 @@ class RatpackTest extends AgentTestRunner {
}
}
}
->>>>>>> 1bfa7e47... Refactor Ratpack
}
def "test path call using ratpack http client"() {
@@ -265,38 +205,6 @@ class RatpackTest extends AgentTestRunner {
// 3rd is the three traces, ratpack, http client 2 and http client 1
// 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)
-<<<<<<< HEAD
- TEST_WRITER.size() == 3
- def trace = TEST_WRITER.get(2)
- trace.size() == 3
- def span = trace[0]
-
- span.context().serviceName == "unnamed-java-app"
- span.context().operationName == "ratpack.handler"
- span.context().resourceName == "GET /"
- span.context().tags["component"] == "ratpack"
- span.context().spanType == DDSpanTypes.HTTP_SERVER
- !span.context().getErrorFlag()
- span.context().tags["http.url"] == "/"
- span.context().tags["http.method"] == "GET"
- span.context().tags["span.kind"] == "server"
- span.context().tags["http.status_code"] == 200
- span.context().tags["thread.name"] != null
- span.context().tags["thread.id"] != null
-
- def clientTrace1 = trace[1] // Second http client call that receives the 'ess' of Success
-
- clientTrace1.context().serviceName == "unnamed-java-app"
- clientTrace1.context().operationName == "ratpack.client-request"
- clientTrace1.context().tags["component"] == "ratpack-httpclient"
- !clientTrace1.context().getErrorFlag()
- clientTrace1.context().tags["http.url"] == "${external.address}nested2"
- clientTrace1.context().tags["http.method"] == "GET"
- clientTrace1.context().tags["span.kind"] == "client"
- clientTrace1.context().tags["http.status_code"] == 200
- clientTrace1.context().tags["thread.name"] != null
- clientTrace1.context().tags["thread.id"] != null
-=======
assertTraces(3) {
// simulated external system, first call
trace(0, 1) {
@@ -308,7 +216,7 @@ class RatpackTest extends AgentTestRunner {
childOf(trace(2).get(2))
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -328,7 +236,7 @@ class RatpackTest extends AgentTestRunner {
childOf(trace(2).get(1))
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -348,7 +256,7 @@ class RatpackTest extends AgentTestRunner {
parent()
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -366,7 +274,7 @@ class RatpackTest extends AgentTestRunner {
childOf(span(0))
errored false
tags {
- "$Tags.COMPONENT.key" "httpclient"
+ "$Tags.COMPONENT.key" "ratpack-httpclient"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
@@ -384,7 +292,7 @@ class RatpackTest extends AgentTestRunner {
childOf(span(0))
errored false
tags {
- "$Tags.COMPONENT.key" "httpclient"
+ "$Tags.COMPONENT.key" "ratpack-httpclient"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
"$Tags.HTTP_METHOD.key" "GET"
@@ -402,29 +310,22 @@ class RatpackTest extends AgentTestRunner {
def app = GroovyEmbeddedApp.ratpack {
handlers {
get {
->>>>>>> 1bfa7e47... Refactor Ratpack
-
final Scope scope = !startSpanInHandler ? GlobalTracer.get().scopeManager().active() :
GlobalTracer.get()
.buildSpan("ratpack.exec-test")
.withTag(DDTags.RESOURCE_NAME, "INSIDE-TEST")
.startActive(true)
-<<<<<<< HEAD
- clientTrace2.context().serviceName == "unnamed-java-app"
- clientTrace2.context().operationName == "ratpack.client-request"
- clientTrace1.context().tags["component"] == "ratpack-httpclient"
- !clientTrace2.context().getErrorFlag()
- clientTrace2.context().tags["http.url"] == "${external.address}nested"
- clientTrace2.context().tags["http.method"] == "GET"
- clientTrace2.context().tags["span.kind"] == "client"
- clientTrace2.context().tags["http.status_code"] == 200
- clientTrace2.context().tags["thread.name"] != null
- clientTrace2.context().tags["thread.id"] != null
-=======
+ if (startSpanInHandler) {
((TraceScope) scope).setAsyncPropagation(true)
+ }
scope.span().setBaggageItem("test-baggage", "foo")
- context.render(testPromise(startSpanInHandler).fork())
+ context.render(testPromise().fork())
+
+ if (startSpanInHandler) {
+ ((TraceScope) scope).setAsyncPropagation(false)
+ }
+ scope.close()
}
}
}
@@ -432,33 +333,17 @@ class RatpackTest extends AgentTestRunner {
.url(app.address.toURL())
.get()
.build()
->>>>>>> 1bfa7e47... Refactor Ratpack
when:
def resp = client.newCall(request).execute()
-<<<<<<< HEAD
- nestedSpan.context().serviceName == "unnamed-java-app"
- nestedSpan.context().operationName == "ratpack.handler"
- nestedSpan.context().resourceName == "GET /nested2"
- nestedSpan.context().tags["component"] == "ratpack"
- nestedSpan.context().spanType == DDSpanTypes.HTTP_SERVER
- !nestedSpan.context().getErrorFlag()
- nestedSpan.context().tags["http.url"] == "/nested2"
- nestedSpan.context().tags["http.method"] == "GET"
- nestedSpan.context().tags["span.kind"] == "server"
- nestedSpan.context().tags["http.status_code"] == 200
- nestedSpan.context().tags["thread.name"] != null
- nestedSpan.context().tags["thread.id"] != null
-=======
then:
resp.code() == 200
resp.body().string() == "foo"
->>>>>>> 1bfa7e47... Refactor Ratpack
assertTraces(1) {
trace(0, (startSpanInHandler ? 2 : 1)) {
- span(0) {
+ span(startSpanInHandler ? 1 : 0) {
resourceName "GET /"
serviceName "unnamed-java-app"
operationName "ratpack.handler"
@@ -466,7 +351,7 @@ class RatpackTest extends AgentTestRunner {
parent()
errored false
tags {
- "$Tags.COMPONENT.key" "handler"
+ "$Tags.COMPONENT.key" "ratpack"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
"$Tags.HTTP_METHOD.key" "GET"
@@ -476,12 +361,12 @@ class RatpackTest extends AgentTestRunner {
}
}
if (startSpanInHandler) {
- span(1) {
+ span(0) {
resourceName "INSIDE-TEST"
serviceName "unnamed-java-app"
operationName "ratpack.exec-test"
spanType DDSpanTypes.HTTP_SERVER
- childOf(span(0))
+ childOf(span(1))
errored false
tags {
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
@@ -492,23 +377,8 @@ class RatpackTest extends AgentTestRunner {
}
}
-<<<<<<< HEAD
- nestedSpan2.context().serviceName == "unnamed-java-app"
- nestedSpan2.context().operationName == "ratpack.handler"
- nestedSpan2.context().resourceName == "GET /nested"
- nestedSpan2.context().tags["component"] == "ratpack"
- nestedSpan2.context().spanType == DDSpanTypes.HTTP_SERVER
- !nestedSpan2.context().getErrorFlag()
- nestedSpan2.context().tags["http.url"] == "/nested"
- nestedSpan2.context().tags["http.method"] == "GET"
- nestedSpan2.context().tags["span.kind"] == "server"
- nestedSpan2.context().tags["http.status_code"] == 200
- nestedSpan2.context().tags["thread.name"] != null
- nestedSpan2.context().tags["thread.id"] != null
-=======
where:
startSpanInHandler << [true, false]
->>>>>>> 1bfa7e47... Refactor Ratpack
}
def "forked executions inherit parent scope"() {
@@ -522,7 +392,7 @@ class RatpackTest extends AgentTestRunner {
((TraceScope) scope).setAsyncPropagation(true)
scope.span().setBaggageItem("test-baggage", "foo")
- ParallelBatch.of(testPromise(false), testPromise(false))
+ ParallelBatch.of(testPromise(), testPromise())
.yield()
.map({ now ->
// close the scope now that we got the baggage inside the promises
@@ -550,15 +420,10 @@ class RatpackTest extends AgentTestRunner {
}
// returns a promise that contains the active scope's "test-baggage" baggage
- // will close an active scope if closeSpan is set to true
- Promise<String> testPromise(boolean closeSpan = true) {
+ Promise<String> testPromise() {
Promise.sync {
Scope tracerScope = GlobalTracer.get().scopeManager().active()
- String res = tracerScope.span().getBaggageItem("test-baggage")
- if (closeSpan) {
- tracerScope.close()
- }
- return res
+ return tracerScope.span().getBaggageItem("test-baggage")
}
}
}

Address comments and add onClose callback on context to close scope.