diff --git a/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/DefaultFilterChainInstrumentation.java b/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/DefaultFilterChainInstrumentation.java index df4773737f5..a37c6d2c76a 100644 --- a/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/DefaultFilterChainInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly-http-2.3.20/src/main/java/datadog/trace/instrumentation/grizzlyhttp232/DefaultFilterChainInstrumentation.java @@ -1,6 +1,9 @@ package datadog.trace.instrumentation.grizzlyhttp232; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPrivate; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -9,7 +12,11 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.InstrumenterConfig; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import java.util.Collections; +import net.bytebuddy.asm.Advice; +import org.glassfish.grizzly.filterchain.FilterChainContext; @AutoService(InstrumenterModule.class) public class DefaultFilterChainInstrumentation extends InstrumenterModule.Tracing @@ -51,5 +58,34 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) .and(takesArgument(1, named("java.lang.Throwable"))), packageName + ".DefaultFilterChainAdvice"); + transformer.applyAdvice( + isMethod() + .and(named("executeFilter")) + .and(takesArgument(2, named("org.glassfish.grizzly.filterchain.FilterChainContext"))), + getClass().getName() + "$PropagateServerSpanAdvice"); + } + + public static class PropagateServerSpanAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AgentScope onEnter(@Advice.Argument(2) final FilterChainContext ctx) { + final AgentSpan active = activeSpan(); + // don't activate a span if already one is active + if (active != null) { + return null; + } + final Object span = ctx.getAttributes().getAttribute(DD_SPAN_ATTRIBUTE); + if (span instanceof AgentSpan) { + // activate the http server span when nothing is already active + return activateSpan((AgentSpan) span); + } + return null; + } + + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + public static void onExit(@Advice.Enter final AgentScope scope) { + if (scope != null) { + scope.close(); + } + } } }