diff --git a/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorBenchmark.java b/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorBenchmark.java index 64ef5377364..42361d7c85f 100644 --- a/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorBenchmark.java +++ b/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorBenchmark.java @@ -1,5 +1,6 @@ package datadog.trace.bootstrap.instrumentation.decorator; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static java.util.concurrent.TimeUnit.MICROSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; @@ -58,7 +59,8 @@ public void setUp() { .build(); GlobalTracer.forceRegister(tracer); decorator = new BenchmarkHttpServerDecorator(); - span = decorator.startSpan(Collections.emptyMap(), (Context) null); + Context context = decorator.startSpan(Collections.emptyMap(), Context.root()); + span = fromContext(context); } @Benchmark @@ -99,7 +101,7 @@ public BenchmarkHttpServerDecorator() { @Override protected String[] instrumentationNames() { - return new String[0]; + return new String[] {"benchmark"}; } @Override diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecorator.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecorator.java index 3119ecd2fe5..bca86637d5d 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecorator.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecorator.java @@ -72,6 +72,7 @@ public abstract class HttpServerDecorator getter = getter(); if (null == carrier || null == getter) { @@ -126,12 +133,22 @@ public Context extract(REQUEST_CARRIER carrier) { return Propagators.defaultPropagator().extract(root(), carrier, getter); } - public AgentSpan startSpan( - String instrumentationName, REQUEST_CARRIER carrier, AgentSpanContext.Extracted context) { + /** + * Starts a span. + * + * @param carrier The request carrier. + * @param context The parent context of the span to create. + * @return A new context bundling the span, child of the given parent context. + */ + public Context startSpan(REQUEST_CARRIER carrier, Context context) { + String[] instrumentationNames = instrumentationNames(); + String instrumentationName = + instrumentationNames != null && instrumentationNames.length > 0 + ? instrumentationNames[0] + : DEFAULT_INSTRUMENTATION_NAME; + AgentSpanContext.Extracted extracted = callIGCallbackStart(context); AgentSpan span = - tracer() - .startSpan(instrumentationName, spanName(), callIGCallbackStart(context)) - .setMeasured(true); + tracer().startSpan(instrumentationName, spanName(), extracted).setMeasured(true); Flow flow = callIGCallbackRequestHeaders(span, carrier); if (flow.getAction() instanceof Flow.Action.RequestBlockingAction) { span.setRequestBlockingAction((Flow.Action.RequestBlockingAction) flow.getAction()); @@ -140,16 +157,7 @@ public AgentSpan startSpan( if (null != carrier && null != getter) { tracer().getDataStreamsMonitoring().setCheckpoint(span, forHttpServer()); } - return span; - } - - public AgentSpan startSpan(REQUEST_CARRIER carrier, Context context) { - return startSpan("http-server", carrier, getExtractedSpanContext(context)); - } - - public AgentSpanContext.Extracted getExtractedSpanContext(Context context) { - AgentSpan extractedSpan = AgentSpan.fromContext(context); - return extractedSpan == null ? null : (AgentSpanContext.Extracted) extractedSpan.context(); + return context.with(span); } public AgentSpan onRequest( @@ -160,6 +168,11 @@ public AgentSpan onRequest( return onRequest(span, connection, request, getExtractedSpanContext(context)); } + public AgentSpanContext.Extracted getExtractedSpanContext(Context context) { + AgentSpan extractedSpan = AgentSpan.fromContext(context); + return extractedSpan == null ? null : (AgentSpanContext.Extracted) extractedSpan.context(); + } + public AgentSpan onRequest( final AgentSpan span, final CONNECTION connection, @@ -375,19 +388,8 @@ public AgentSpan onResponse(final AgentSpan span, final RESPONSE response) { return span; } - // @Override - // public Span onError(final Span span, final Throwable throwable) { - // assert span != null; - // // FIXME - // final Object status = span.getTag("http.status"); - // if (status == null || status.equals(200)) { - // // Ensure status set correctly - // span.setTag("http.status", 500); - // } - // return super.onError(span, throwable); - // } - - private AgentSpanContext.Extracted callIGCallbackStart(AgentSpanContext.Extracted context) { + private AgentSpanContext.Extracted callIGCallbackStart(final Context context) { + AgentSpanContext.Extracted extracted = getExtractedSpanContext(context); AgentTracer.TracerAPI tracer = tracer(); Supplier> startedCbAppSec = tracer.getCallbackProvider(RequestContextSlot.APPSEC).getCallback(EVENTS.requestStarted()); @@ -395,14 +397,14 @@ private AgentSpanContext.Extracted callIGCallbackStart(AgentSpanContext.Extracte tracer.getCallbackProvider(RequestContextSlot.IAST).getCallback(EVENTS.requestStarted()); if (startedCbAppSec == null && startedCbIast == null) { - return context; + return extracted; } TagContext tagContext = null; - if (context == null) { + if (extracted == null) { tagContext = new TagContext(); - } else if (context instanceof TagContext) { - tagContext = (TagContext) context; + } else if (extracted instanceof TagContext) { + tagContext = (TagContext) extracted; } if (tagContext != null) { @@ -415,7 +417,7 @@ private AgentSpanContext.Extracted callIGCallbackStart(AgentSpanContext.Extracte return tagContext; } - return context; + return extracted; } @Override diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorTest.groovy index 14261722ad1..d038fbdac26 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorTest.groovy @@ -25,6 +25,7 @@ import datadog.trace.core.datastreams.DataStreamsMonitoring import java.util.function.Function import java.util.function.Supplier +import static datadog.context.Context.root import static datadog.trace.api.config.TraceInstrumentationConfig.HTTP_SERVER_DECODED_RESOURCE_PRESERVE_SPACES import static datadog.trace.api.config.TraceInstrumentationConfig.HTTP_SERVER_RAW_QUERY_STRING import static datadog.trace.api.config.TraceInstrumentationConfig.HTTP_SERVER_RAW_RESOURCE @@ -497,7 +498,7 @@ class HttpServerDecoratorTest extends ServerDecoratorTest { def decorator = newDecorator(mTracer, null) when: - decorator.startSpan("test", headers, null) + decorator.startSpan(headers, root()) then: 1 * mSpan.setMeasured(true) >> mSpan diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/DatadogWrapperHelper.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/DatadogWrapperHelper.java index de08a4094fa..4c45b352c83 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/DatadogWrapperHelper.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/DatadogWrapperHelper.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.akkahttp; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.instrumentation.akkahttp.AkkaHttpServerDecorator.DECORATE; import akka.http.scaladsl.model.HttpRequest; @@ -10,12 +11,13 @@ public class DatadogWrapperHelper { public static ContextScope createSpan(final HttpRequest request) { - final Context context = DECORATE.extract(request); - final AgentSpan span = DECORATE.startSpan(request, context); + final Context parentContext = DECORATE.extract(request); + final Context context = DECORATE.startSpan(request, parentContext); + final AgentSpan span = fromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, request, request, context); + DECORATE.onRequest(span, request, request, parentContext); - return context.with(span).attach(); + return context.attach(); } public static void finishSpan(final AgentSpan span, final HttpResponse response) { diff --git a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsDecorator.java b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsDecorator.java index a7654462b91..3a778f986b7 100644 --- a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsDecorator.java +++ b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsDecorator.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.azurefunctions; +package datadog.trace.instrumentation.azure.functions; import com.microsoft.azure.functions.HttpRequestMessage; import com.microsoft.azure.functions.HttpResponseMessage; diff --git a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsInstrumentation.java b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsInstrumentation.java index 039f90cec8d..472f45bbc77 100644 --- a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsInstrumentation.java +++ b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/AzureFunctionsInstrumentation.java @@ -1,11 +1,11 @@ -package datadog.trace.instrumentation.azurefunctions; +package datadog.trace.instrumentation.azure.functions; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.declaresMethod; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.isAnnotatedWith; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; -import static datadog.trace.instrumentation.azurefunctions.AzureFunctionsDecorator.DECORATE; +import static datadog.trace.instrumentation.azure.functions.AzureFunctionsDecorator.DECORATE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -65,15 +65,16 @@ public void methodAdvice(MethodTransformer transformer) { public static class AzureFunctionsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static ContextScope methodEnter( - @Advice.Argument(0) final HttpRequestMessage request, - @Advice.Argument(1) final ExecutionContext context) { - final Context extractedContext = DECORATE.extract(request); - final AgentSpan span = DECORATE.startSpan(request, extractedContext); - DECORATE.afterStart(span, context.getFunctionName()); - DECORATE.onRequest(span, request, request, extractedContext); + @Advice.Argument(0) final HttpRequestMessage request, + @Advice.Argument(1) final ExecutionContext executionContext) { + final Context parentContext = DECORATE.extract(request); + final Context context = DECORATE.startSpan(request, parentContext); + final AgentSpan span = fromContext(context); + DECORATE.afterStart(span, executionContext.getFunctionName()); + DECORATE.onRequest(span, request, request, parentContext); HTTP_RESOURCE_DECORATOR.withRoute( span, request.getHttpMethod().name(), request.getUri().getPath()); - return extractedContext.with(span).attach(); + return context.attach(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) @@ -81,7 +82,7 @@ public static void methodExit( @Advice.Enter final ContextScope scope, @Advice.Return final HttpResponseMessage response, @Advice.Thrown final Throwable throwable) { - final AgentSpan span = spanFromContext(scope.context()); + final AgentSpan span = fromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.onResponse(span, response); DECORATE.beforeFinish(span); diff --git a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/HttpRequestMessageExtractAdapter.java b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/HttpRequestMessageExtractAdapter.java index 60b3ad86b8f..e9c43a5c752 100644 --- a/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/HttpRequestMessageExtractAdapter.java +++ b/dd-java-agent/instrumentation/azure-functions/src/main/java/datadog/trace/instrumentation/azure/functions/HttpRequestMessageExtractAdapter.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.azurefunctions; +package datadog.trace.instrumentation.azure.functions; import com.microsoft.azure.functions.HttpRequestMessage; import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; diff --git a/dd-java-agent/instrumentation/grizzly-2/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java b/dd-java-agent/instrumentation/grizzly-2/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java index 70087d86b80..cc12314e046 100644 --- a/dd-java-agent/instrumentation/grizzly-2/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly-2/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java @@ -13,7 +13,6 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -74,15 +73,17 @@ public static class HandleAdvice { } final Context parentContext = DECORATE.extract(request); - final AgentSpan span = DECORATE.startSpan(request, parentContext); + final Context context = DECORATE.startSpan(request, parentContext); + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); DECORATE.onRequest(span, request, request, parentContext); - scope = parentContext.with(span).attach(); + scope = context.attach(); request.setAttribute(DD_SPAN_ATTRIBUTE, span); - request.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - request.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + request.setAttribute( + CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + request.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); Flow.Action.RequestBlockingAction rba = span.getRequestBlockingAction(); if (rba != null) { diff --git a/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/GrizzlyDecorator.java b/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/GrizzlyDecorator.java index ac4dc89cd8c..978a0d65824 100644 --- a/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/GrizzlyDecorator.java +++ b/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/GrizzlyDecorator.java @@ -1,5 +1,7 @@ package datadog.trace.instrumentation.grizzlyhttp232; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; + import datadog.appsec.api.blocking.BlockingContentType; import datadog.context.Context; import datadog.context.ContextScope; @@ -112,13 +114,14 @@ public static NextAction onHttpCodecFilterExit( } HttpRequestPacket httpRequest = (HttpRequestPacket) httpHeader; HttpResponsePacket httpResponse = httpRequest.getResponse(); - Context context = DECORATE.extract(httpRequest); - AgentSpan span = DECORATE.startSpan(httpRequest, context); - ContextScope scope = context.with(span).attach(); + Context parentContext = DECORATE.extract(httpRequest); + Context context = DECORATE.startSpan(httpRequest, parentContext); + ContextScope scope = context.attach(); + AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); ctx.getAttributes().setAttribute(DD_SPAN_ATTRIBUTE, span); ctx.getAttributes().setAttribute(DD_RESPONSE_ATTRIBUTE, httpResponse); - DECORATE.onRequest(span, httpRequest, httpRequest, context); + DECORATE.onRequest(span, httpRequest, httpRequest, parentContext); Flow.Action.RequestBlockingAction rba = span.getRequestBlockingAction(); if (rba != null && thiz instanceof HttpServerFilter) { diff --git a/dd-java-agent/instrumentation/jetty-11/src/main/java11/datadog/trace/instrumentation/jetty11/JettyServerAdvice.java b/dd-java-agent/instrumentation/jetty-11/src/main/java11/datadog/trace/instrumentation/jetty11/JettyServerAdvice.java index d0b48b884df..65dbaffbe4e 100644 --- a/dd-java-agent/instrumentation/jetty-11/src/main/java11/datadog/trace/instrumentation/jetty11/JettyServerAdvice.java +++ b/dd-java-agent/instrumentation/jetty-11/src/main/java11/datadog/trace/instrumentation/jetty11/JettyServerAdvice.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.jetty11; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.instrumentation.jetty11.JettyDecorator.DECORATE; @@ -7,7 +8,6 @@ import datadog.context.Context; import datadog.context.ContextScope; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.server.HttpChannel; @@ -26,16 +26,17 @@ public static ContextScope onEnter( return activateSpan((AgentSpan) existingSpan); } - final Context context = DECORATE.extract(req); - span = DECORATE.startSpan(req, context); - final ContextScope scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + final ContextScope scope = context.attach(); + span = fromContext(context); span.setMeasured(true); DECORATE.afterStart(span); - DECORATE.onRequest(span, req, req, context); + DECORATE.onRequest(span, req, req, parentContext); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/jetty-11/src/test/groovy/HttpChannelAppSecTest.groovy b/dd-java-agent/instrumentation/jetty-11/src/test/groovy/HttpChannelAppSecTest.groovy index 37bc5c8c5bd..4cff73246b2 100644 --- a/dd-java-agent/instrumentation/jetty-11/src/test/groovy/HttpChannelAppSecTest.groovy +++ b/dd-java-agent/instrumentation/jetty-11/src/test/groovy/HttpChannelAppSecTest.groovy @@ -73,7 +73,7 @@ class HttpChannelAppSecTest extends AgentTestRunner { @Override void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - if ('datadog/trace/bootstrap/instrumentation/api/AgentSpan' == owner && 'getRequestBlockingAction' == name) { + if ('datadog/trace/instrumentation/jetty/JettyBlockingHelper' == owner && 'hasRequestBlockingAction' == name) { blockApplied = true } super.visitMethodInsn(opcode, owner, name, descriptor, isInterface) diff --git a/dd-java-agent/instrumentation/jetty-12/src/main/java17/datadog/trace/instrumentation/jetty12/JettyServerAdvice.java b/dd-java-agent/instrumentation/jetty-12/src/main/java17/datadog/trace/instrumentation/jetty12/JettyServerAdvice.java index e905262b791..ed8c193b334 100644 --- a/dd-java-agent/instrumentation/jetty-12/src/main/java17/datadog/trace/instrumentation/jetty12/JettyServerAdvice.java +++ b/dd-java-agent/instrumentation/jetty-12/src/main/java17/datadog/trace/instrumentation/jetty12/JettyServerAdvice.java @@ -1,11 +1,12 @@ package datadog.trace.instrumentation.jetty12; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; +import static datadog.trace.instrumentation.jetty12.JettyDecorator.DECORATE; import datadog.context.Context; import datadog.context.ContextScope; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.server.Request; @@ -27,16 +28,17 @@ public static void onExit( } } - final Context context = JettyDecorator.DECORATE.extract(req); - final AgentSpan span = JettyDecorator.DECORATE.startSpan(req, context); - try (final ContextScope scope = context.with(span).attach()) { + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + try (final ContextScope ignored = context.attach()) { + final AgentSpan span = fromContext(context); span.setMeasured(true); - JettyDecorator.DECORATE.afterStart(span); - JettyDecorator.DECORATE.onRequest(span, req, req, context); + DECORATE.afterStart(span); + DECORATE.onRequest(span, req, req, parentContext); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); ret = JettyRunnableWrapper.wrapIfNeeded(ret); } } @@ -53,8 +55,8 @@ public static void stopSpan(@Advice.This final HttpChannelState channel) { Object spanObj = req.getAttribute(DD_SPAN_ATTRIBUTE); if (spanObj instanceof AgentSpan) { final AgentSpan span = (AgentSpan) spanObj; - JettyDecorator.DECORATE.onResponse(span, channel); - JettyDecorator.DECORATE.beforeFinish(span); + DECORATE.onResponse(span, channel); + DECORATE.beforeFinish(span); span.finish(); } } diff --git a/dd-java-agent/instrumentation/jetty-7.0/src/main/java/datadog/trace/instrumentation/jetty70/JettyServerInstrumentation.java b/dd-java-agent/instrumentation/jetty-7.0/src/main/java/datadog/trace/instrumentation/jetty70/JettyServerInstrumentation.java index 36c1e6599c2..af7f8a4c7d6 100644 --- a/dd-java-agent/instrumentation/jetty-7.0/src/main/java/datadog/trace/instrumentation/jetty70/JettyServerInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty-7.0/src/main/java/datadog/trace/instrumentation/jetty70/JettyServerInstrumentation.java @@ -1,6 +1,7 @@ package datadog.trace.instrumentation.jetty70; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.instrumentation.jetty70.JettyDecorator.DECORATE; import static java.util.Collections.singletonMap; @@ -15,7 +16,6 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.ProductActivation; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -155,15 +155,16 @@ public static ContextScope onEnter( return ((AgentSpan) existingSpan).attach(); } - final Context extractedContext = DECORATE.extract(req); - span = DECORATE.startSpan(req, extractedContext); - final ContextScope scope = extractedContext.with(span).attach(); + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + final ContextScope scope = context.attach(); + span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, req, req, extractedContext); + DECORATE.onRequest(span, req, req, parentContext); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/jetty-7.6/src/main/java/datadog/trace/instrumentation/jetty76/JettyServerInstrumentation.java b/dd-java-agent/instrumentation/jetty-7.6/src/main/java/datadog/trace/instrumentation/jetty76/JettyServerInstrumentation.java index a49026a983b..ec9ef262fb1 100644 --- a/dd-java-agent/instrumentation/jetty-7.6/src/main/java/datadog/trace/instrumentation/jetty76/JettyServerInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty-7.6/src/main/java/datadog/trace/instrumentation/jetty76/JettyServerInstrumentation.java @@ -1,6 +1,7 @@ package datadog.trace.instrumentation.jetty76; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_FIN_DISP_LIST_SPAN_ATTRIBUTE; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.instrumentation.jetty76.JettyDecorator.DECORATE; @@ -15,7 +16,6 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.ProductActivation; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -156,15 +156,16 @@ public static ContextScope onEnter( return ((AgentSpan) existingSpan).attach(); } - final Context extractedContext = DECORATE.extract(req); - span = DECORATE.startSpan(req, extractedContext); - final ContextScope scope = extractedContext.with(span).attach(); + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + final ContextScope scope = context.attach(); + span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, req, req, extractedContext); + DECORATE.onRequest(span, req, req, parentContext); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/jetty-9/src/main/java/datadog/trace/instrumentation/jetty9/JettyServerInstrumentation.java b/dd-java-agent/instrumentation/jetty-9/src/main/java/datadog/trace/instrumentation/jetty9/JettyServerInstrumentation.java index 94fd9171e22..b85a639fb2b 100644 --- a/dd-java-agent/instrumentation/jetty-9/src/main/java/datadog/trace/instrumentation/jetty9/JettyServerInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty-9/src/main/java/datadog/trace/instrumentation/jetty9/JettyServerInstrumentation.java @@ -3,6 +3,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.declaresMethod; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.ExcludeType.RUNNABLE; import static datadog.trace.instrumentation.jetty9.JettyDecorator.DECORATE; @@ -21,7 +22,6 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.ProductActivation; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; @@ -170,15 +170,16 @@ public static ContextScope onEnter( return ((AgentSpan) existingSpan).attach(); } - final Context context = DECORATE.extract(req); - span = DECORATE.startSpan(req, context); - final ContextScope scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + final ContextScope scope = context.attach(); + span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, req, req, context); + DECORATE.onRequest(span, req, req, parentContext); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/DispatchableAdvice.java b/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/DispatchableAdvice.java index b0f0b53f037..5ea02dccb66 100644 --- a/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/DispatchableAdvice.java +++ b/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/DispatchableAdvice.java @@ -1,8 +1,6 @@ package datadog.trace.instrumentation.jetty10; -import datadog.trace.api.gateway.Flow; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.context.Context; import datadog.trace.instrumentation.jetty.JettyBlockingHelper; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.server.HttpChannel; @@ -10,17 +8,7 @@ public class DispatchableAdvice { @Advice.OnMethodEnter(suppress = Throwable.class, skipOn = Advice.OnNonDefaultValue.class) public static boolean /* skip */ before(@Advice.FieldValue("this$0") HttpChannel channel) { - AgentSpan span = AgentTracer.activeSpan(); - if (span == null) { - return false; - } - Flow.Action.RequestBlockingAction rba = span.getRequestBlockingAction(); - if (rba == null) { - return false; - } - - boolean blocked = - JettyBlockingHelper.block(channel.getRequest(), channel.getResponse(), rba, span); - return blocked; + return JettyBlockingHelper.block( + channel.getRequest(), channel.getResponse(), Context.current()); } } diff --git a/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/HandleAdvice.java b/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/HandleAdvice.java index e8e9ffc6a6b..ece1c7720d2 100644 --- a/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/HandleAdvice.java +++ b/dd-java-agent/instrumentation/jetty-9/src/main/java_jetty10/datadog/trace/instrumentation/jetty10/HandleAdvice.java @@ -1,12 +1,12 @@ package datadog.trace.instrumentation.jetty10; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.instrumentation.jetty10.JettyDecorator.DECORATE; import datadog.context.Context; import datadog.context.ContextScope; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.server.HttpChannel; @@ -24,15 +24,16 @@ public static ContextScope onEnter( return ((AgentSpan) existingSpan).attach(); } - final Context context = DECORATE.extract(req); - span = DECORATE.startSpan(req, context); + final Context parentContext = DECORATE.extract(req); + final Context context = DECORATE.startSpan(req, parentContext); + span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, req, req, context); + DECORATE.onRequest(span, req, req, parentContext); - final ContextScope scope = context.with(span).attach(); + final ContextScope scope = context.attach(); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/HandleRequestVisitor.java b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/HandleRequestVisitor.java index a1924d4a4b5..e8081846844 100644 --- a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/HandleRequestVisitor.java +++ b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/HandleRequestVisitor.java @@ -1,7 +1,9 @@ package datadog.trace.instrumentation.jetty; -import datadog.trace.api.gateway.Flow; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import static net.bytebuddy.jar.asm.Opcodes.INVOKESTATIC; + +import datadog.context.Context; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import java.util.List; import net.bytebuddy.jar.asm.Label; import net.bytebuddy.jar.asm.MethodVisitor; @@ -15,23 +17,18 @@ * and replaces it with: * *
- * if (span != null && span.getRequestBlockingAction() &&
- *     JettyBlockingHelper.block(
- *         this.getRequest(), this.getResponse(),
- *         span.getRequestBlockingAction(), span) {
+ * if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), Java8BytecodeBridge.getCurrentContext()) {
  *   // nothing
  * } else {
  *   server.handle(this);
  * }
  * 
* - *

It needs first to get the index of the span variable that's set when a new span is created. + *

It needs first to get the index of the context variable that's set when a new span is created. */ public class HandleRequestVisitor extends MethodVisitor { private static final Logger log = LoggerFactory.getLogger(HandleRequestVisitor.class); - private boolean lookForStore; - private int agentSpanVar = -1; private final int classVersion; private final String connClassInternalName; private boolean success; @@ -53,13 +50,7 @@ DelayLoadsMethodVisitor delayVisitorDelegate() { @Override public void visitMethodInsn( int opcode, String owner, String name, String descriptor, boolean isInterface) { - if (agentSpanVar == -1) { - lookForStore = - !lookForStore - && opcode == Opcodes.INVOKEVIRTUAL - && name.equals("startSpan") - && descriptor.endsWith("Ldatadog/trace/bootstrap/instrumentation/api/AgentSpan;"); - } else if (opcode == Opcodes.INVOKEVIRTUAL + if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("org/eclipse/jetty/server/Server") && name.equals("handle") && descriptor.equals("(L" + this.connClassInternalName + ";)V")) { @@ -71,26 +62,9 @@ public void visitMethodInsn( return; } - Label doBlockLabel = new Label(); - Label beforeHandle = new Label(); Label afterHandle = new Label(); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); - super.visitJumpInsn(Opcodes.IFNULL, beforeHandle); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); - super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitJumpInsn(Opcodes.IFNONNULL, doBlockLabel); - super.visitJumpInsn(Opcodes.GOTO, beforeHandle); - - super.visitLabel(doBlockLabel); - if (needsStackFrames()) { - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - } + // Add Request, Response and Context onto the stack super.visitVarInsn(Opcodes.ALOAD, 0); super.visitMethodInsn( Opcodes.INVOKEVIRTUAL, @@ -105,31 +79,29 @@ public void visitMethodInsn( "getResponse", "()Lorg/eclipse/jetty/server/Response;", false); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); + super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); + INVOKESTATIC, + Type.getInternalName(Java8BytecodeBridge.class), + "getCurrentContext", + "()Ldatadog/context/Context;", + false); + // Call JettyBlockingHelper.block(request, response, context) super.visitMethodInsn( Opcodes.INVOKESTATIC, Type.getInternalName(JettyBlockingHelper.class), "block", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;" - + Type.getDescriptor(Flow.Action.RequestBlockingAction.class) - + Type.getDescriptor(AgentSpan.class) + + Type.getDescriptor(Context.class) + ")Z", false); + // Jump after handle if blocked super.visitJumpInsn(Opcodes.IFNE, afterHandle); - super.visitLabel(beforeHandle); - if (needsStackFrames()) { - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - } + // Inject default handle instructions mv.commitLoads(savedLoads); super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + // Add after handle label super.visitLabel(afterHandle); if (needsStackFrames()) { super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); @@ -141,16 +113,6 @@ public void visitMethodInsn( super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); } - @Override - public void visitVarInsn(int opcode, int varIndex) { - if (lookForStore && opcode == Opcodes.ASTORE) { - agentSpanVar = varIndex; - lookForStore = false; - } - - super.visitVarInsn(opcode, varIndex); - } - @Override public void visitEnd() { if (!success) { diff --git a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/JettyBlockingHelper.java b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/JettyBlockingHelper.java index 983b53ec9a4..57667466b7b 100644 --- a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/JettyBlockingHelper.java +++ b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty/JettyBlockingHelper.java @@ -1,11 +1,13 @@ package datadog.trace.instrumentation.jetty; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static java.lang.invoke.MethodHandles.collectArguments; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodType.methodType; import datadog.appsec.api.blocking.BlockingContentType; import datadog.appsec.api.blocking.BlockingException; +import datadog.context.Context; import datadog.trace.api.gateway.Flow; import datadog.trace.api.internal.TraceSegment; import datadog.trace.bootstrap.blocking.BlockingActionHelper; @@ -225,8 +227,12 @@ public static boolean block( return true; } - public static boolean block( - Request request, Response response, Flow.Action.RequestBlockingAction rba, AgentSpan span) { + public static boolean block(Request request, Response response, Context context) { + AgentSpan span = spanFromContext(context); + Flow.Action.RequestBlockingAction rba; + if (span == null || (rba = span.getRequestBlockingAction()) == null) { + return false; + } return block( span.getRequestContext().getTraceSegment(), request, @@ -236,9 +242,13 @@ public static boolean block( rba.getExtraHeaders()); } - public static void blockAndThrowOnFailure( - Request request, Response response, Flow.Action.RequestBlockingAction rba, AgentSpan span) { - if (!block(request, response, rba, span)) { + public static boolean hasRequestBlockingAction(Context context) { + AgentSpan span = spanFromContext(context); + return span != null && span.getRequestBlockingAction() != null; + } + + public static void blockAndThrowOnFailure(Request request, Response response, Context context) { + if (!block(request, response, context)) { throw new BlockingException("Throwing after being unable to commit blocking response"); } } diff --git a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/DelayCertainInsMethodVisitor.java b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/DelayCertainInsMethodVisitor.java index 46e32fcaecf..3efe79f571a 100644 --- a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/DelayCertainInsMethodVisitor.java +++ b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/DelayCertainInsMethodVisitor.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import net.bytebuddy.jar.asm.AnnotationVisitor; import net.bytebuddy.jar.asm.Handle; import net.bytebuddy.jar.asm.Label; @@ -10,22 +9,34 @@ import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.TypePath; +/** + * This method visitor delays the following instructions: + * + *

    + *
  • Local variable instruction: {@code ALOAD}, + *
  • field instructions: {@code GETSTATIC}, {@code GETFIELD} + *
  • method instructions: {@code INVOKEVIRTUAL} + *
+ * + * They can be queried using {@link #transferVisitations()} and manually commited using {@link + * #commitVisitations(List)}. + */ public class DelayCertainInsMethodVisitor extends MethodVisitor { - private final List heldVisitations = new ArrayList(); + private final List heldVisitations = new ArrayList<>(); public DelayCertainInsMethodVisitor(int api, MethodVisitor methodVisitor) { super(api, methodVisitor); } - public void commitVisitations(List heldVisitations) { - for (Function fun : heldVisitations) { - fun.apply(null); + public void commitVisitations(List heldVisitations) { + for (Runnable r : heldVisitations) { + r.run(); } heldVisitations.clear(); } - public List transferVisitations() { - ArrayList copy = new ArrayList<>(this.heldVisitations); + public List transferVisitations() { + ArrayList copy = new ArrayList<>(this.heldVisitations); this.heldVisitations.clear(); return copy; } @@ -207,7 +218,7 @@ public void visitEnd() { super.visitEnd(); } - public class InvokeDynamicInsn implements Function { + public class InvokeDynamicInsn implements Runnable { public final String name; public final String descriptor; public final Handle bootstrapMethodHandle; @@ -225,13 +236,12 @@ public InvokeDynamicInsn( } @Override - public Object apply(Object input) { + public void run() { mv.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - return null; } } - public class VirtualMethodInsn implements Function { + public class VirtualMethodInsn implements Runnable { public final int opcode; public final String owner; public final String name; @@ -248,13 +258,12 @@ public VirtualMethodInsn( } @Override - public Object apply(Object input) { + public void run() { mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - return null; } } - public class GetStaticFieldInsn implements Function { + public class GetStaticFieldInsn implements Runnable { public final int opcode; public final String owner; public final String name; @@ -268,13 +277,12 @@ public GetStaticFieldInsn(int opcode, String owner, String name, String descript } @Override - public Object apply(Object input) { + public void run() { mv.visitFieldInsn(opcode, owner, name, descriptor); - return null; } } - public class GetFieldInsn implements Function { + public class GetFieldInsn implements Runnable { public final int opcode; public final String owner; public final String name; @@ -288,13 +296,12 @@ public GetFieldInsn(int opcode, String owner, String name, String descriptor) { } @Override - public Object apply(Object input) { + public void run() { mv.visitFieldInsn(opcode, owner, name, descriptor); - return null; } } - public class ALoadVarInsn implements Function { + public class ALoadVarInsn implements Runnable { public final int opcode; public final int varIndex; @@ -304,9 +311,8 @@ public ALoadVarInsn(int opcode, int varIndex) { } @Override - public Object apply(Object input) { + public void run() { mv.visitVarInsn(opcode, varIndex); - return null; } } } diff --git a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/HandleVisitor.java b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/HandleVisitor.java index 66e8d9e4dfc..6fe101a3a10 100644 --- a/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/HandleVisitor.java +++ b/dd-java-agent/instrumentation/jetty-common/src/main/java/datadog/trace/instrumentation/jetty9/HandleVisitor.java @@ -1,11 +1,19 @@ package datadog.trace.instrumentation.jetty9; -import datadog.trace.api.gateway.Flow; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import static net.bytebuddy.jar.asm.Opcodes.ALOAD; +import static net.bytebuddy.jar.asm.Opcodes.F_SAME; +import static net.bytebuddy.jar.asm.Opcodes.GOTO; +import static net.bytebuddy.jar.asm.Opcodes.H_INVOKESTATIC; +import static net.bytebuddy.jar.asm.Opcodes.IFEQ; +import static net.bytebuddy.jar.asm.Opcodes.IFNE; +import static net.bytebuddy.jar.asm.Opcodes.INVOKESTATIC; +import static net.bytebuddy.jar.asm.Opcodes.INVOKEVIRTUAL; + +import datadog.context.Context; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import datadog.trace.instrumentation.jetty.JettyBlockingHelper; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import net.bytebuddy.jar.asm.Handle; import net.bytebuddy.jar.asm.Label; import net.bytebuddy.jar.asm.MethodVisitor; @@ -18,20 +26,29 @@ * Instruments the handle (or run) method to put the calls to getServer().handle(this) * under a condition, for the {@link org.eclipse.jetty.server.HttpChannel} class. * - *

In particular, for earlier versions of jetty: + *

In particular, for earlier versions of jetty: + * + *

  *   case REQUEST_DISPATCH:
  *   // ...
  *   getServer().handle(this);
- *  is replaced with: 
+ * 
+ * + * is replaced with: + * + *
  *   case REQUEST_DISPATCH:
  *   // ...
- *   if (span != null && span.getBlockingAction() != null &&
- *       JettyBlockingHelper.block(this.getRequest(), this.getResponse())) {
+ *   if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), Java8BytecodeBridge.getCurrentContext())) {
  *     // nothing
  *   } else {
  *     getServer().handle(this);
  *   }
- *  And for later versions of Jetty before 11.16.0, 
+ * 
+ * + * And for later versions of Jetty before 11.16.0, + * + *
  *   case DISPATCH:
  *   {
  *     // ...
@@ -40,16 +57,20 @@
  *         // ...
  *         getServer().handle(HttpChannel.this);
  *       });
- *  is replaced with: 
+ * 
+ * + * is replaced with: + * + *
  *   case DISPATCH:
  *   {
  *     // ...
- *     if (span != null && span.getBlockingAction() != null) {
+ *     if (JettyBlockingHelper.hasBlockingRequest(Java8BytecodeBridge.getCurrentContext()) {
  *       Request req = getRequest(); // actually on the stack only
  *       Response resp = getResponse(); // idem
+ *       Context context = Java8BytecodeBridge.getCurrentContext() // idem
  *       dispatch(DispatcherType.REQUEST, () -> {
- *         JettyBlockingHelper.blockAndThrowOnFailure(
- *             request, response, span.getBlockingAction(), span);
+ *         JettyBlockingHelper.blockAndThrowOnFailure(request, response, context);
  *       });
  *     } else {
  *       dispatch(DispatcherType.REQUEST, () -> {
@@ -57,33 +78,40 @@
  *         getServer().handle(HttpChannel.this);
  *       });
  *   }
- *  And for later versions of Jetty, 
+ * 
+ * + * And for later versions of Jetty, + * + *
  *   case DISPATCH:
  *   {
  *     // ...
  *     dispatch(DispatcherType.REQUEST, _requestDispatcher);
- *  is replaced with: 
+ * 
+ * + * is replaced with: + * + *
  *   case DISPATCH:
  *   {
  *     // ...
- *     if (span != null && span.getBlockingAction() != null) {
+ *     if (JettyBlockingHelper.hasBlockingRequest(Java8BytecodeBridge.getCurrentContext()) {
  *       Request req = getRequest(); // actually on the stack only
  *       Response resp = getResponse(); // idem
+ *       Context context = Java8BytecodeBridge.getCurrentContext() // idem
  *       dispatch(DispatcherType.REQUEST, () -> {
- *         JettyBlockingHelper.blockAndThrowOnFailure(
- *             request, response, span.getBlockingAction(), span);
+ *         JettyBlockingHelper.blockAndThrowOnFailure(request, response, context);
  *       });
  *     } else {
  *       dispatch(DispatcherType.REQUEST, _requestDispatcher);
  *   }
- * 
+ * 
*/ public class HandleVisitor extends MethodVisitor { private static final Logger log = LoggerFactory.getLogger(HandleVisitor.class); - - private boolean lookForStore; - private int agentSpanVar = -1; + /** Whether the handle() method injection was successful . */ private boolean success; + private final String methodName; public HandleVisitor(int api, DelayCertainInsMethodVisitor methodVisitor, String methodName) { @@ -98,19 +126,13 @@ DelayCertainInsMethodVisitor delayVisitorDelegate() { @Override public void visitMethodInsn( int opcode, String owner, String name, String descriptor, boolean isInterface) { - if (agentSpanVar == -1) { - lookForStore = - !lookForStore - && opcode == Opcodes.INVOKEVIRTUAL - && name.equals("startSpan") - && descriptor.endsWith("Ldatadog/trace/bootstrap/instrumentation/api/AgentSpan;"); - } else if (!success - && opcode == Opcodes.INVOKEVIRTUAL + if (!success + && opcode == INVOKEVIRTUAL && owner.equals("org/eclipse/jetty/server/Server") && name.equals("handle") && descriptor.equals("(Lorg/eclipse/jetty/server/HttpChannel;)V")) { DelayCertainInsMethodVisitor mv = delayVisitorDelegate(); - List savedVisitations = mv.transferVisitations(); + List savedVisitations = mv.transferVisitations(); /* * Saved visitations should be for: * @@ -124,67 +146,52 @@ public void visitMethodInsn( return; } - Label doBlockLabel = new Label(); - Label beforeHandle = new Label(); + // Declare label to insert after Server.handle() call Label afterHandle = new Label(); - - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); - super.visitJumpInsn(Opcodes.IFNULL, beforeHandle); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); - super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitJumpInsn(Opcodes.IFNONNULL, doBlockLabel); - super.visitJumpInsn(Opcodes.GOTO, beforeHandle); - - super.visitLabel(doBlockLabel); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - super.visitVarInsn(Opcodes.ALOAD, 0); + // Inject blocking helper call and get its three parameters onto the stack: + // - Request + // - Response + // - Context -- retrieved from current as attached just earlier from tracing instrumentation + super.visitVarInsn(ALOAD, 0); super.visitMethodInsn( - Opcodes.INVOKEVIRTUAL, + INVOKEVIRTUAL, "org/eclipse/jetty/server/HttpChannel", "getRequest", "()Lorg/eclipse/jetty/server/Request;", false); - super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitVarInsn(ALOAD, 0); super.visitMethodInsn( - Opcodes.INVOKEVIRTUAL, + INVOKEVIRTUAL, "org/eclipse/jetty/server/HttpChannel", "getResponse", "()Lorg/eclipse/jetty/server/Response;", false); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); + INVOKESTATIC, + Type.getInternalName(Java8BytecodeBridge.class), + "getCurrentContext", + "()Ldatadog/context/Context;", + false); super.visitMethodInsn( - Opcodes.INVOKESTATIC, + INVOKESTATIC, Type.getInternalName(JettyBlockingHelper.class), "block", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;" - + Type.getDescriptor(Flow.Action.RequestBlockingAction.class) - + Type.getDescriptor(AgentSpan.class) + + Type.getDescriptor(Context.class) + ")Z", false); - super.visitJumpInsn(Opcodes.IFNE, afterHandle); - - super.visitLabel(beforeHandle); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + // Inject jump to after Server.handle() call if blocked + super.visitJumpInsn(IFNE, afterHandle); + // Inject getServer() and Server.handle() calls mv.commitVisitations(savedVisitations); super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + // Inject label after Server.handle() call to jump here when blocked super.visitLabel(afterHandle); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + super.visitFrame(F_SAME, 0, null, 0, null); this.success = true; return; } else if (!success - && (opcode == Opcodes.INVOKESPECIAL || opcode == Opcodes.INVOKEVIRTUAL) + && (opcode == Opcodes.INVOKESPECIAL || opcode == INVOKEVIRTUAL) && owner.equals("org/eclipse/jetty/server/HttpChannel") && name.equals("dispatch") && (descriptor.equals( @@ -193,7 +200,7 @@ public void visitMethodInsn( "(Ljakarta/servlet/DispatcherType;Lorg/eclipse/jetty/server/HttpChannel$Dispatchable;)V"))) { DelayCertainInsMethodVisitor mv = delayVisitorDelegate(); - List savedVisitations = mv.transferVisitations(); + List savedVisitations = mv.transferVisitations(); // check that we've queued up what we're supposed to if (!checkDispatchMethodState(savedVisitations)) { @@ -201,71 +208,60 @@ public void visitMethodInsn( return; } - DelayCertainInsMethodVisitor.GetStaticFieldInsn getStaticFieldInsn = - (DelayCertainInsMethodVisitor.GetStaticFieldInsn) savedVisitations.get(1); - if ((!getStaticFieldInsn.owner.equals("javax/servlet/DispatcherType") - && !getStaticFieldInsn.owner.equals("jakarta/servlet/DispatcherType")) - || !getStaticFieldInsn.name.equals("REQUEST")) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - return; - } - - Label doBlockLabel = new Label(); Label beforeRegularDispatch = new Label(); Label afterRegularDispatch = new Label(); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); - super.visitJumpInsn(Opcodes.IFNULL, beforeRegularDispatch); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); + // Add current context to the stack + super.visitMethodInsn( + INVOKESTATIC, + Type.getInternalName(Java8BytecodeBridge.class), + "getCurrentContext", + "()Ldatadog/context/Context;", + false); + // Call JettyBlockingHelper.hasRequestBlockingAction(context) super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitJumpInsn(Opcodes.IFNONNULL, doBlockLabel); - super.visitJumpInsn(Opcodes.GOTO, beforeRegularDispatch); + INVOKESTATIC, + Type.getInternalName(JettyBlockingHelper.class), + "hasRequestBlockingAction", + "(" + Type.getDescriptor(Context.class) + ")Z", + false); + // If no request blocking action, jump before the regular dispatch + super.visitJumpInsn(IFEQ, beforeRegularDispatch); - super.visitLabel(doBlockLabel); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); // dispatch with a Dispatchable created from JettyBlockingHelper::block // first set up the first two arguments to dispatch (this and DispatcherType.REQUEST) - List loadThisAndEnum = new ArrayList<>(savedVisitations.subList(0, 2)); + List loadThisAndEnum = new ArrayList<>(savedVisitations.subList(0, 2)); mv.commitVisitations(loadThisAndEnum); - // set up the arguments to the method underlying the lambda (Request, Response, - // RequestBlockingAction, AgentSpan) - super.visitVarInsn(Opcodes.ALOAD, 0); + // set up the arguments to the method underlying the lambda (Request, Response, Context) + super.visitVarInsn(ALOAD, 0); super.visitMethodInsn( - Opcodes.INVOKEVIRTUAL, + INVOKEVIRTUAL, "org/eclipse/jetty/server/HttpChannel", "getRequest", "()Lorg/eclipse/jetty/server/Request;", false); - super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitVarInsn(ALOAD, 0); super.visitMethodInsn( - Opcodes.INVOKEVIRTUAL, + INVOKEVIRTUAL, "org/eclipse/jetty/server/HttpChannel", "getResponse", "()Lorg/eclipse/jetty/server/Response;", false); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); super.visitMethodInsn( - Opcodes.INVOKEINTERFACE, - "datadog/trace/bootstrap/instrumentation/api/AgentSpan", - "getRequestBlockingAction", - "()" + Type.getDescriptor(Flow.Action.RequestBlockingAction.class), - true); - super.visitVarInsn(Opcodes.ALOAD, agentSpanVar); + INVOKESTATIC, + Type.getInternalName(Java8BytecodeBridge.class), + "getCurrentContext", + "()Ldatadog/context/Context;", + false); // create the lambda super.visitInvokeDynamicInsn( "dispatch", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;" - + Type.getDescriptor(Flow.Action.RequestBlockingAction.class) - + Type.getDescriptor(AgentSpan.class) + + Type.getDescriptor(Context.class) + ")Lorg/eclipse/jetty/server/HttpChannel$Dispatchable;", new Handle( - Opcodes.H_INVOKESTATIC, + H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", @@ -273,12 +269,11 @@ public void visitMethodInsn( new Object[] { Type.getType("()V"), new Handle( - Opcodes.H_INVOKESTATIC, + H_INVOKESTATIC, Type.getInternalName(JettyBlockingHelper.class), "blockAndThrowOnFailure", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;" - + Type.getDescriptor(Flow.Action.RequestBlockingAction.class) - + Type.getDescriptor(AgentSpan.class) + + Type.getDescriptor(Context.class) + ")V", false), Type.getType("()V") @@ -287,14 +282,14 @@ public void visitMethodInsn( // invoke the dispatch method super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - super.visitJumpInsn(Opcodes.GOTO, afterRegularDispatch); + super.visitJumpInsn(GOTO, afterRegularDispatch); super.visitLabel(beforeRegularDispatch); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + super.visitFrame(F_SAME, 0, null, 0, null); mv.commitVisitations(savedVisitations); super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); super.visitLabel(afterRegularDispatch); - super.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + super.visitFrame(F_SAME, 0, null, 0, null); this.success = true; return; } @@ -302,7 +297,7 @@ public void visitMethodInsn( super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); } - private boolean checkDispatchMethodState(final List savedVisitations) { + private boolean checkDispatchMethodState(final List savedVisitations) { if (savedVisitations.size() != 4) { return false; } @@ -315,6 +310,13 @@ private boolean checkDispatchMethodState(final List savedVisitations) if (!(savedVisitations.get(1) instanceof DelayCertainInsMethodVisitor.GetStaticFieldInsn)) { return false; } + DelayCertainInsMethodVisitor.GetStaticFieldInsn getStaticFieldInsn = + (DelayCertainInsMethodVisitor.GetStaticFieldInsn) savedVisitations.get(1); + if ((!getStaticFieldInsn.owner.equals("javax/servlet/DispatcherType") + && !getStaticFieldInsn.owner.equals("jakarta/servlet/DispatcherType")) + || !getStaticFieldInsn.name.equals("REQUEST")) { + return false; + } // push this to the stack (to create the lambda or access the instance field, which depends on // this) @@ -322,7 +324,7 @@ private boolean checkDispatchMethodState(final List savedVisitations) return false; } - final Function last = savedVisitations.get(3); + final Runnable last = savedVisitations.get(3); // jetty < 11.16.0 // this.dispatch(DispatcherType.REQUEST, () -> { ... }); if (last instanceof DelayCertainInsMethodVisitor.InvokeDynamicInsn) { @@ -334,16 +336,6 @@ private boolean checkDispatchMethodState(final List savedVisitations) return last instanceof DelayCertainInsMethodVisitor.GetFieldInsn; } - @Override - public void visitVarInsn(int opcode, int varIndex) { - if (lookForStore && opcode == Opcodes.ASTORE) { - agentSpanVar = varIndex; - lookForStore = false; - } - - super.visitVarInsn(opcode, varIndex); - } - @Override public void visitEnd() { if (!success && !"run".equals(methodName)) { diff --git a/dd-java-agent/instrumentation/jetty-common/src/test/groovy/datadog/trace/instrumentation/jetty/JettyBlockingHelperSpecification.groovy b/dd-java-agent/instrumentation/jetty-common/src/test/groovy/datadog/trace/instrumentation/jetty/JettyBlockingHelperSpecification.groovy index 7f8f29129e4..f1b5173cfd2 100644 --- a/dd-java-agent/instrumentation/jetty-common/src/test/groovy/datadog/trace/instrumentation/jetty/JettyBlockingHelperSpecification.groovy +++ b/dd-java-agent/instrumentation/jetty-common/src/test/groovy/datadog/trace/instrumentation/jetty/JettyBlockingHelperSpecification.groovy @@ -1,27 +1,40 @@ package datadog.trace.instrumentation.jetty import datadog.trace.api.gateway.Flow +import datadog.trace.api.gateway.RequestContext import datadog.trace.api.internal.TraceSegment -import datadog.trace.test.util.DDSpecification +import datadog.trace.bootstrap.instrumentation.api.AgentSpan import org.eclipse.jetty.server.Request import org.eclipse.jetty.server.Response +import spock.lang.Specification import javax.servlet.ServletOutputStream import static datadog.appsec.api.blocking.BlockingContentType.AUTO -class JettyBlockingHelperSpecification extends DDSpecification { - void 'block completes successfully'() { +// WARNING: Test is never found nor run +class JettyBlockingHelperSpecification extends Specification { + def 'block completes successfully'() { setup: Request req = Mock() Response resp = Mock() ServletOutputStream os = Mock() TraceSegment seg = Mock() + def rba = new Flow.Action.RequestBlockingAction(402, AUTO) + RequestContext requestContext = Stub(RequestContext) { + getTraceSegment() >> seg + getBlockResponseFunction() >> rba + } + AgentSpan span = Stub(AgentSpan) { + getRequestContext() >> requestContext + getRequestBlockingAction() >> rba + } when: - JettyBlockingHelper.block(seg, req, resp, new Flow.Action.RequestBlockingAction(402, AUTO)) + JettyBlockingHelper.block(req, resp, span) then: + false == true // Proof test is never run 1 * resp.isCommitted() >> false 1 * resp.setStatus(402) 1 * req.getHeader('Accept') >> 'text/html' diff --git a/dd-java-agent/instrumentation/liberty-20/src/main/java/datadog/trace/instrumentation/liberty20/LibertyServerInstrumentation.java b/dd-java-agent/instrumentation/liberty-20/src/main/java/datadog/trace/instrumentation/liberty20/LibertyServerInstrumentation.java index c05349a3e2d..80b94a4377e 100644 --- a/dd-java-agent/instrumentation/liberty-20/src/main/java/datadog/trace/instrumentation/liberty20/LibertyServerInstrumentation.java +++ b/dd-java-agent/instrumentation/liberty-20/src/main/java/datadog/trace/instrumentation/liberty20/LibertyServerInstrumentation.java @@ -1,7 +1,7 @@ package datadog.trace.instrumentation.liberty20; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.instrumentation.liberty20.HttpInboundServiceContextImplInstrumentation.REQUEST_MSG_TYPE; import static datadog.trace.instrumentation.liberty20.LibertyDecorator.DD_EXTRACTED_CONTEXT_ATTRIBUTE; import static datadog.trace.instrumentation.liberty20.LibertyDecorator.DD_SPAN_ATTRIBUTE; @@ -21,7 +21,6 @@ import datadog.trace.api.ClassloaderConfigurationOverrides; import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.bootstrap.ActiveSubsystems; import datadog.trace.bootstrap.ContextStore; @@ -105,10 +104,11 @@ public static class HandleRequestAdvice { } catch (NullPointerException e) { } - final Context context = DECORATE.extract(request); - request.setAttribute(DD_EXTRACTED_CONTEXT_ATTRIBUTE, context); - final AgentSpan span = DECORATE.startSpan(request, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(request); + request.setAttribute(DD_EXTRACTED_CONTEXT_ATTRIBUTE, parentContext); + final Context context = DECORATE.startSpan(request, parentContext); + scope = context.attach(); + final AgentSpan span = fromContext(context); if (Config.get().isJeeSplitByDeployment()) { final IWebAppDispatcherContext dispatcherContext = request.getWebAppDispatcherContext(); if (dispatcherContext != null) { @@ -122,10 +122,11 @@ public static class HandleRequestAdvice { } } DECORATE.afterStart(span); - DECORATE.onRequest(span, request, request, context); + DECORATE.onRequest(span, request, request, parentContext); request.setAttribute(DD_SPAN_ATTRIBUTE, span); - request.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - request.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + request.setAttribute( + CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + request.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); if (ActiveSubsystems.APPSEC_ACTIVE) { ContextStore store = @@ -163,7 +164,7 @@ public static void closeScope( // this has the unfortunate consequence that service name (as set via the tag interceptor) // of the top span won't match that of its child spans, because it's instead the original // one that will propagate - DECORATE.getPath(spanFromContext(scope.context()), request); + DECORATE.getPath(fromContext(scope.context()), request); scope.close(); } } diff --git a/dd-java-agent/instrumentation/liberty-23/src/main/java/datadog/trace/instrumentation/liberty23/LibertyServerInstrumentation.java b/dd-java-agent/instrumentation/liberty-23/src/main/java/datadog/trace/instrumentation/liberty23/LibertyServerInstrumentation.java index 81cd81bd91b..efe145611cd 100644 --- a/dd-java-agent/instrumentation/liberty-23/src/main/java/datadog/trace/instrumentation/liberty23/LibertyServerInstrumentation.java +++ b/dd-java-agent/instrumentation/liberty-23/src/main/java/datadog/trace/instrumentation/liberty23/LibertyServerInstrumentation.java @@ -1,7 +1,7 @@ package datadog.trace.instrumentation.liberty23; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.instrumentation.liberty23.HttpInboundServiceContextImplInstrumentation.REQUEST_MSG_TYPE; import static datadog.trace.instrumentation.liberty23.LibertyDecorator.DD_EXTRACTED_CONTEXT_ATTRIBUTE; import static datadog.trace.instrumentation.liberty23.LibertyDecorator.DD_SPAN_ATTRIBUTE; @@ -21,7 +21,6 @@ import datadog.trace.api.ClassloaderConfigurationOverrides; import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.bootstrap.ActiveSubsystems; import datadog.trace.bootstrap.ContextStore; @@ -107,10 +106,11 @@ public static class HandleRequestAdvice { } catch (NullPointerException e) { } - final Context context = DECORATE.extract(request); - request.setAttribute(DD_EXTRACTED_CONTEXT_ATTRIBUTE, context); - final AgentSpan span = DECORATE.startSpan(request, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(request); + request.setAttribute(DD_EXTRACTED_CONTEXT_ATTRIBUTE, parentContext); + final Context context = DECORATE.startSpan(request, parentContext); + scope = context.attach(); + final AgentSpan span = fromContext(context); if (Config.get().isJeeSplitByDeployment()) { final IWebAppDispatcherContext dispatcherContext = request.getWebAppDispatcherContext(); if (dispatcherContext != null) { @@ -124,10 +124,11 @@ public static class HandleRequestAdvice { } } DECORATE.afterStart(span); - DECORATE.onRequest(span, request, request, context); + DECORATE.onRequest(span, request, request, parentContext); request.setAttribute(DD_SPAN_ATTRIBUTE, span); - request.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - request.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + request.setAttribute( + CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + request.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); if (ActiveSubsystems.APPSEC_ACTIVE) { ContextStore store = InstrumentationContext.get( @@ -165,7 +166,7 @@ public static void closeScope( // this has the unfortunate consequence that service name (as set via the tag interceptor) // of the top span won't match that of its child spans, because it's instead the original // one that will propagate - DECORATE.getPath(spanFromContext(scope.context()), request); + DECORATE.getPath(fromContext(scope.context()), request); scope.close(); } } diff --git a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java index 4fbe1d16777..862dc01cb2d 100644 --- a/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/server/HttpServerRequestTracingHandler.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.netty38.server; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.netty38.server.NettyHttpServerDecorator.DECORATE; import datadog.context.Context; @@ -43,15 +44,16 @@ public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent final HttpRequest request = (HttpRequest) msg.getMessage(); final HttpHeaders headers = request.headers(); - final Context context = DECORATE.extract(headers); - final AgentSpan span = DECORATE.startSpan(headers, context); + final Context parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); channelTraceContext.reset(); channelTraceContext.setRequestHeaders(headers); - try (final ContextScope scope = context.with(span).attach()) { + try (final ContextScope scope = context.attach()) { + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, ctx.getChannel(), request, context); + DECORATE.onRequest(span, ctx.getChannel(), request, parentContext); channelTraceContext.setServerSpan(span); diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java index 49caacd7a91..58bb49cb647 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.netty40.server; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.netty40.AttributeKeys.ANALYZED_RESPONSE_KEY; import static datadog.trace.instrumentation.netty40.AttributeKeys.BLOCKED_RESPONSE_KEY; import static datadog.trace.instrumentation.netty40.AttributeKeys.REQUEST_HEADERS_ATTRIBUTE_KEY; @@ -39,12 +40,13 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) { final HttpRequest request = (HttpRequest) msg; final HttpHeaders headers = request.headers(); - final Context context = DECORATE.extract(headers); - final AgentSpan span = DECORATE.startSpan(headers, context); + final Context parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); - try (final ContextScope scope = context.with(span).attach()) { + try (final ContextScope ignored = context.attach()) { + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, channel, request, context); + DECORATE.onRequest(span, channel, request, parentContext); channel.attr(ANALYZED_RESPONSE_KEY).set(null); channel.attr(BLOCKED_RESPONSE_KEY).set(null); diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java index 6d91b9ea8b6..30197668254 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.netty41.server; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.netty41.AttributeKeys.ANALYZED_RESPONSE_KEY; import static datadog.trace.instrumentation.netty41.AttributeKeys.BLOCKED_RESPONSE_KEY; import static datadog.trace.instrumentation.netty41.AttributeKeys.REQUEST_HEADERS_ATTRIBUTE_KEY; @@ -38,12 +39,13 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) { final HttpRequest request = (HttpRequest) msg; final HttpHeaders headers = request.headers(); - final Context context = DECORATE.extract(headers); - final AgentSpan span = DECORATE.startSpan(headers, context); + final Context parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); - try (final ContextScope scope = context.with(span).attach()) { + try (final ContextScope ignored = context.attach()) { + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, channel, request, context); + DECORATE.onRequest(span, channel, request, parentContext); channel.attr(ANALYZED_RESPONSE_KEY).set(null); channel.attr(BLOCKED_RESPONSE_KEY).set(null); diff --git a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/DatadogWrapperHelper.java b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/DatadogWrapperHelper.java index af83f9b8809..5c15a75fa46 100644 --- a/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/DatadogWrapperHelper.java +++ b/dd-java-agent/instrumentation/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/DatadogWrapperHelper.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.pekkohttp; +import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext; import static datadog.trace.instrumentation.pekkohttp.PekkoHttpServerDecorator.DECORATE; import datadog.context.Context; @@ -10,12 +11,13 @@ public class DatadogWrapperHelper { public static ContextScope createSpan(final HttpRequest request) { - final Context context = DECORATE.extract(request); - final AgentSpan span = DECORATE.startSpan(request, context); + final Context parentContext = DECORATE.extract(request); + final Context context = DECORATE.startSpan(request, parentContext); + final AgentSpan span = fromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, request, request, context); + DECORATE.onRequest(span, request, request, parentContext); - return context.with(span).attach(); + return context.attach(); } public static void finishSpan(final AgentSpan span, final HttpResponse response) { diff --git a/dd-java-agent/instrumentation/play-2.3/src/main/java/datadog/trace/instrumentation/play23/PlayAdvice.java b/dd-java-agent/instrumentation/play-2.3/src/main/java/datadog/trace/instrumentation/play23/PlayAdvice.java index f9db932bff3..07145401713 100644 --- a/dd-java-agent/instrumentation/play-2.3/src/main/java/datadog/trace/instrumentation/play23/PlayAdvice.java +++ b/dd-java-agent/instrumentation/play-2.3/src/main/java/datadog/trace/instrumentation/play23/PlayAdvice.java @@ -20,18 +20,19 @@ public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ContextScope onEnter(@Advice.Argument(0) final Request req) { + public static ContextScope onEnter(@Advice.Argument(0) final Request req) { final AgentSpan span; final ContextScope scope; if (activeSpan() == null) { Headers headers = req.headers(); - final Context context = DECORATE.extract(headers); - span = DECORATE.startSpan(headers, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); + span = spanFromContext(context); + scope = context.attach(); } else { // An upstream framework (e.g. akka-http, netty) has already started the span. // Do not extract the context. - span = startSpan(PLAY_REQUEST); + span = startSpan("play", PLAY_REQUEST); span.setMeasured(true); scope = span.attach(); } @@ -45,7 +46,7 @@ public static void stopTraceOnResponse( @Advice.Enter final ContextScope playControllerScope, @Advice.This final Object thisAction, @Advice.Thrown final Throwable throwable, - @Advice.Argument(0) final Request req, + @Advice.Argument(0) final Request req, @Advice.Return(readOnly = false) final Future responseFuture) { final AgentSpan playControllerSpan = spanFromContext(playControllerScope.context()); @@ -55,7 +56,7 @@ public static void stopTraceOnResponse( if (throwable == null) { responseFuture.onComplete( new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + ((Action) thisAction).executionContext()); } else { DECORATE.onError(playControllerSpan, throwable); if (REPORT_HTTP_STATUS) { diff --git a/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play24/PlayAdvice.java b/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play24/PlayAdvice.java index 1193ebedf7c..f40924bb90f 100644 --- a/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play24/PlayAdvice.java +++ b/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play24/PlayAdvice.java @@ -20,7 +20,7 @@ public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ContextScope onEnter(@Advice.Argument(value = 0, readOnly = false) Request req) { + public static ContextScope onEnter(@Advice.Argument(value = 0, readOnly = false) Request req) { final AgentSpan span; final ContextScope scope; @@ -31,13 +31,14 @@ public static ContextScope onEnter(@Advice.Argument(value = 0, readOnly = false) if (activeSpan() == null) { final Headers headers = req.headers(); - final Context context = DECORATE.extract(headers); - span = DECORATE.startSpan(headers, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); + span = spanFromContext(context); + scope = context.attach(); } else { // An upstream framework (e.g. akka-http, netty) has already started the span. // Do not extract the context. - span = startSpan(PLAY_REQUEST); + span = startSpan("play", PLAY_REQUEST); span.setMeasured(true); scope = span.attach(); } @@ -58,7 +59,7 @@ public static void stopTraceOnResponse( @Advice.Enter final ContextScope playControllerScope, @Advice.This final Object thisAction, @Advice.Thrown final Throwable throwable, - @Advice.Argument(0) final Request req, + @Advice.Argument(0) final Request req, @Advice.Return(readOnly = false) final Future responseFuture) { if (playControllerScope == null) { @@ -70,7 +71,7 @@ public static void stopTraceOnResponse( if (throwable == null) { responseFuture.onComplete( new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + ((Action) thisAction).executionContext()); } else { DECORATE.onError(playControllerSpan, throwable); if (REPORT_HTTP_STATUS) { diff --git a/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayAdvice.java b/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayAdvice.java index 1e222ae2848..4aee183c204 100644 --- a/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayAdvice.java +++ b/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayAdvice.java @@ -9,6 +9,7 @@ import datadog.context.Context; import datadog.context.ContextScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; import net.bytebuddy.asm.Advice; import play.api.mvc.Action; @@ -19,9 +20,8 @@ public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ContextScope onEnter( - @Advice.Argument(value = 0, readOnly = false) Request req, - @Advice.Local("extractedContext") Context extractedContext) { + public static ContextScope onEnter(@Advice.Argument(value = 0, readOnly = false) Request req) { + final Context parentContext; final AgentSpan span; final ContextScope scope; @@ -32,13 +32,15 @@ public static ContextScope onEnter( if (activeSpan() == null) { final Headers headers = req.headers(); - extractedContext = DECORATE.extract(headers); - span = DECORATE.startSpan(headers, extractedContext); - scope = extractedContext.with(span).attach(); + parentContext = DECORATE.extract(headers); + final Context context = DECORATE.startSpan(headers, parentContext); + span = spanFromContext(context); + scope = context.attach(); } else { // An upstream framework (e.g. akka-http, netty) has already started the span. // Do not extract the context. - span = startSpan(PLAY_REQUEST); + parentContext = Java8BytecodeBridge.getRootContext(); + span = startSpan("play", PLAY_REQUEST); scope = span.attach(); } @@ -49,7 +51,7 @@ public static ContextScope onEnter( // Moved from OnMethodExit // Call onRequest on return after tags are populated. - DECORATE.onRequest(span, req, req, extractedContext); + DECORATE.onRequest(span, req, req, parentContext); return scope; } @@ -57,10 +59,9 @@ public static ContextScope onEnter( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopTraceOnResponse( @Advice.Enter final ContextScope playControllerScope, - @Advice.Local("extractedContext") Context extractedContext, @Advice.This final Object thisAction, @Advice.Thrown final Throwable throwable, - @Advice.Argument(0) final Request req, + @Advice.Argument(0) final Request req, @Advice.Return(readOnly = false) final Future responseFuture) { if (playControllerScope == null) { @@ -72,7 +73,7 @@ public static void stopTraceOnResponse( if (throwable == null) { responseFuture.onComplete( new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + ((Action) thisAction).executionContext()); } else { DECORATE.onError(playControllerSpan, throwable); DECORATE.beforeFinish(playControllerSpan); diff --git a/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayHttpServerDecorator.java b/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayHttpServerDecorator.java index 1979bebad98..d4c5851df76 100644 --- a/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayHttpServerDecorator.java +++ b/dd-java-agent/instrumentation/play-2.6/src/main/java/datadog/trace/instrumentation/play26/PlayHttpServerDecorator.java @@ -3,6 +3,7 @@ import static datadog.trace.api.gateway.Events.EVENTS; import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR; +import datadog.context.Context; import datadog.trace.api.Config; import datadog.trace.api.cache.DDCache; import datadog.trace.api.cache.DDCaches; @@ -11,7 +12,6 @@ import datadog.trace.api.gateway.RequestContextSlot; import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext; import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities; import datadog.trace.bootstrap.instrumentation.api.URIDataAdapter; import datadog.trace.bootstrap.instrumentation.api.URIUtils; @@ -36,7 +36,7 @@ import scala.Option; public class PlayHttpServerDecorator - extends HttpServerDecorator { + extends HttpServerDecorator, Request, Result, Headers> { private static final Logger LOG = LoggerFactory.getLogger(PlayHttpServerDecorator.class); public static final boolean REPORT_HTTP_STATUS = Config.get().getPlayReportHttpStatus(); public static final CharSequence PLAY_REQUEST = UTF8BytesString.create("play.request"); @@ -96,17 +96,17 @@ public CharSequence spanName() { } @Override - protected String method(final Request httpRequest) { + protected String method(final Request httpRequest) { return httpRequest.method(); } @Override - protected URIDataAdapter url(final Request request) { + protected URIDataAdapter url(final Request request) { return new RequestURIDataAdapter(request); } @Override - protected String peerHostIP(final Request request) { + protected String peerHostIP(final Request request) { RemoteConnection connection = request.connection(); if (connection instanceof RemoteConnectionWithRawAddress) { return ((RemoteConnectionWithRawAddress) connection).rawRemoteAddressString(); @@ -116,7 +116,7 @@ protected String peerHostIP(final Request request) { } @Override - protected int peerPort(final Request request) { + protected int peerPort(final Request request) { return 0; } @@ -128,9 +128,9 @@ protected int status(final Result httpResponse) { @Override public AgentSpan onRequest( final AgentSpan span, - final Request connection, - final Request request, - AgentSpanContext.Extracted context) { + final Request connection, + final Request request, + final Context context) { super.onRequest(span, connection, request, context); if (request != null) { // more about routes here: diff --git a/dd-java-agent/instrumentation/restlet-2.2/src/main/java/datadog/trace/instrumentation/restlet/RestletInstrumentation.java b/dd-java-agent/instrumentation/restlet-2.2/src/main/java/datadog/trace/instrumentation/restlet/RestletInstrumentation.java index 1ce2aee65aa..6c6b16a938c 100644 --- a/dd-java-agent/instrumentation/restlet-2.2/src/main/java/datadog/trace/instrumentation/restlet/RestletInstrumentation.java +++ b/dd-java-agent/instrumentation/restlet-2.2/src/main/java/datadog/trace/instrumentation/restlet/RestletInstrumentation.java @@ -54,11 +54,12 @@ public String[] helperClassNames() { public static class RestletHandleAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static ContextScope beginRequest(@Advice.Argument(0) final HttpExchange exchange) { - Context context = DECORATE.extract(exchange); - AgentSpan span = DECORATE.startSpan(exchange, context); - ContextScope scope = context.with(span).attach(); + Context parentContext = DECORATE.extract(exchange); + Context context = DECORATE.startSpan(exchange, parentContext); + AgentSpan span = spanFromContext(context); + ContextScope scope = context.attach(); DECORATE.afterStart(span); - DECORATE.onRequest(span, exchange, exchange, context); + DECORATE.onRequest(span, exchange, exchange, parentContext); DECORATE.onPeerConnection(span, exchange.getRemoteAddress()); return scope; diff --git a/dd-java-agent/instrumentation/servlet/request-2/src/main/java/datadog/trace/instrumentation/servlet2/Servlet2Advice.java b/dd-java-agent/instrumentation/servlet/request-2/src/main/java/datadog/trace/instrumentation/servlet2/Servlet2Advice.java index 5cb76142b87..120fbb039a0 100644 --- a/dd-java-agent/instrumentation/servlet/request-2/src/main/java/datadog/trace/instrumentation/servlet2/Servlet2Advice.java +++ b/dd-java-agent/instrumentation/servlet/request-2/src/main/java/datadog/trace/instrumentation/servlet2/Servlet2Advice.java @@ -10,7 +10,6 @@ import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.DDTags; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -52,17 +51,18 @@ public static boolean onEnter( InstrumentationContext.get(ServletResponse.class, Integer.class).put(response, 200); } - final Context context = DECORATE.extract(httpServletRequest); - final AgentSpan span = DECORATE.startSpan(httpServletRequest, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(httpServletRequest); + final Context context = DECORATE.startSpan(httpServletRequest, parentContext); + scope = context.attach(); + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, httpServletRequest, httpServletRequest, context); + DECORATE.onRequest(span, httpServletRequest, httpServletRequest, parentContext); httpServletRequest.setAttribute(DD_SPAN_ATTRIBUTE, span); httpServletRequest.setAttribute( - CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); + CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); httpServletRequest.setAttribute( - CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); Flow.Action.RequestBlockingAction rba = span.getRequestBlockingAction(); if (rba != null) { diff --git a/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/Servlet3Advice.java b/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/Servlet3Advice.java index 96755749047..a06cbda8c59 100644 --- a/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/Servlet3Advice.java +++ b/dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/Servlet3Advice.java @@ -14,7 +14,6 @@ import datadog.trace.api.Config; import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.DDTags; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.api.rum.RumInjector; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -84,18 +83,19 @@ public static boolean onEnter( return false; } - final Context context = DECORATE.extract(httpServletRequest); - final AgentSpan span = DECORATE.startSpan(httpServletRequest, context); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(httpServletRequest); + final Context context = DECORATE.startSpan(httpServletRequest, parentContext); + scope = context.attach(); + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, httpServletRequest, httpServletRequest, context); + DECORATE.onRequest(span, httpServletRequest, httpServletRequest, parentContext); httpServletRequest.setAttribute(DD_SPAN_ATTRIBUTE, span); httpServletRequest.setAttribute( - CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); + CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); httpServletRequest.setAttribute( - CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); Flow.Action.RequestBlockingAction rba = span.getRequestBlockingAction(); if (rba != null) { diff --git a/dd-java-agent/instrumentation/spray-1.3/src/main/scala/datadog/trace/instrumentation/spray/SprayHttpServerRunSealedRouteAdvice.java b/dd-java-agent/instrumentation/spray-1.3/src/main/scala/datadog/trace/instrumentation/spray/SprayHttpServerRunSealedRouteAdvice.java index 20aa80a5fe5..f2aa29be00e 100644 --- a/dd-java-agent/instrumentation/spray-1.3/src/main/scala/datadog/trace/instrumentation/spray/SprayHttpServerRunSealedRouteAdvice.java +++ b/dd-java-agent/instrumentation/spray-1.3/src/main/scala/datadog/trace/instrumentation/spray/SprayHttpServerRunSealedRouteAdvice.java @@ -2,6 +2,7 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.spray.SprayHttpServerDecorator.DECORATE; import datadog.context.Context; @@ -23,13 +24,13 @@ public static ContextScope enter( // Propagate context in case income request was going through several routes // TODO: Add test for it final HttpRequest request = ctx.request(); - Context extractedContext = DECORATE.extract(request); - extractedSpanContext = DECORATE.getExtractedSpanContext(extractedContext); - span = DECORATE.startSpan(request, extractedContext); - context = extractedContext.with(span); + Context parentContext = DECORATE.extract(request); + extractedSpanContext = DECORATE.getExtractedSpanContext(parentContext); + context = DECORATE.startSpan(request, parentContext); + span = spanFromContext(context); } else { extractedSpanContext = null; - span = startSpan(DECORATE.spanName()); + span = startSpan("spray", DECORATE.spanName()); context = span; } diff --git a/dd-java-agent/instrumentation/synapse-3/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerInstrumentation.java b/dd-java-agent/instrumentation/synapse-3/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerInstrumentation.java index 8325230b889..6a01290b458 100644 --- a/dd-java-agent/instrumentation/synapse-3/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerInstrumentation.java +++ b/dd-java-agent/instrumentation/synapse-3/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerInstrumentation.java @@ -2,7 +2,6 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.synapse3.SynapseServerDecorator.DECORATE; import static datadog.trace.instrumentation.synapse3.SynapseServerDecorator.SYNAPSE_SPAN_KEY; @@ -68,18 +67,10 @@ public static ContextScope beginRequest( // check incoming request for distributed trace ids HttpRequest request = connection.getHttpRequest(); - Context context = DECORATE.extract(request); - - AgentSpan span; - if (null != context) { - span = DECORATE.startSpan(request, context); - context = context.with(span); - } else { - span = startSpan(DECORATE.spanName()); - span.setMeasured(true); - context = span; - } + Context parentContext = DECORATE.extract(request); + Context context = DECORATE.startSpan(request, parentContext); ContextScope scope = context.attach(); + AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); DECORATE.onRequest(span, connection, request, context); diff --git a/dd-java-agent/instrumentation/tomcat-5.5/src/main/java/datadog/trace/instrumentation/tomcat/TomcatServerInstrumentation.java b/dd-java-agent/instrumentation/tomcat-5.5/src/main/java/datadog/trace/instrumentation/tomcat/TomcatServerInstrumentation.java index f1d91a5fb61..5a3ed4dee6f 100644 --- a/dd-java-agent/instrumentation/tomcat-5.5/src/main/java/datadog/trace/instrumentation/tomcat/TomcatServerInstrumentation.java +++ b/dd-java-agent/instrumentation/tomcat-5.5/src/main/java/datadog/trace/instrumentation/tomcat/TomcatServerInstrumentation.java @@ -4,6 +4,7 @@ import static datadog.trace.agent.tooling.muzzle.Reference.EXPECTS_NON_STATIC; import static datadog.trace.agent.tooling.muzzle.Reference.EXPECTS_PUBLIC; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.ExcludeType.RUNNABLE; import static datadog.trace.instrumentation.tomcat.TomcatDecorator.DD_EXTRACTED_CONTEXT_ATTRIBUTE; @@ -19,7 +20,6 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; import datadog.trace.api.CorrelationIdentifier; -import datadog.trace.api.GlobalTracer; import datadog.trace.api.gateway.Flow; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext; @@ -123,21 +123,22 @@ public static ContextScope onService(@Advice.Argument(0) org.apache.coyote.Reque return activateSpan((AgentSpan) existingSpan); } - final Context extractedContext = DECORATE.extract(req); + final Context parentContext = DECORATE.extract(req); // TODO: Migrate setting DD_EXTRACTED_CONTEXT_ATTRIBUTE from AgentSpanContext.Extracted to // Context req.setAttribute( - DD_EXTRACTED_CONTEXT_ATTRIBUTE, DECORATE.getExtractedSpanContext(extractedContext)); + DD_EXTRACTED_CONTEXT_ATTRIBUTE, DECORATE.getExtractedSpanContext(parentContext)); - final AgentSpan span = DECORATE.startSpan(req, extractedContext); - final ContextScope scope = extractedContext.with(span).attach(); + final Context context = DECORATE.startSpan(req, parentContext); + final ContextScope scope = context.attach(); // This span is finished when Request.recycle() is called by RequestInstrumentation. + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); req.setAttribute(DD_SPAN_ATTRIBUTE, span); - req.setAttribute(CorrelationIdentifier.getTraceIdKey(), GlobalTracer.get().getTraceId()); - req.setAttribute(CorrelationIdentifier.getSpanIdKey(), GlobalTracer.get().getSpanId()); + req.setAttribute(CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + req.setAttribute(CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); return scope; } diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HandlerInstrumentation.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HandlerInstrumentation.java index 52021dc16ca..81ba04a99d1 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HandlerInstrumentation.java @@ -2,6 +2,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.undertow.UndertowBlockingHandler.REQUEST_BLOCKING_DATA; import static datadog.trace.instrumentation.undertow.UndertowBlockingHandler.TRACE_SEGMENT; import static datadog.trace.instrumentation.undertow.UndertowDecorator.DD_UNDERTOW_CONTINUATION; @@ -93,11 +94,12 @@ public static void onEnter( return; } - final Context extractedContext = DECORATE.extract(exchange); - final AgentSpan span = DECORATE.startSpan(exchange, extractedContext).setMeasured(true); - scope = extractedContext.with(span).attach(); + final Context parentContext = DECORATE.extract(exchange); + final Context context = DECORATE.startSpan(exchange, parentContext); + scope = context.attach(); + final AgentSpan span = spanFromContext(context); DECORATE.afterStart(span); - DECORATE.onRequest(span, exchange, exchange, extractedContext); + DECORATE.onRequest(span, exchange, exchange, parentContext); exchange.putAttachment(DD_UNDERTOW_CONTINUATION, captureSpan(span)); diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java index 1df726e3790..5977c2af5b4 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java @@ -3,6 +3,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.undertow.UndertowDecorator.DECORATE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -74,11 +75,12 @@ public static void afterRequestParse( ContextScope scope = null; try { if (span == null) { - final Context context = DECORATE.extract(exchange); - span = DECORATE.startSpan(exchange, context).setMeasured(true); - scope = context.with(span).attach(); + final Context parentContext = DECORATE.extract(exchange); + final Context context = DECORATE.startSpan(exchange, parentContext); + span = spanFromContext(context); + scope = context.attach(); DECORATE.afterStart(span); - DECORATE.onRequest(span, exchange, exchange, context); + DECORATE.onRequest(span, exchange, exchange, parentContext); } DECORATE.onError(span, throwable); // because we know that a http 400 will be thrown