Merge pull request #1196 from DataDog/tyler/fix-span-attribute
Set dispatcher span on request instead of clear
This commit is contained in:
commit
848476316d
|
@ -71,6 +71,7 @@ public final class RequestDispatcherInstrumentation extends Instrumenter.Default
|
||||||
public static AgentScope start(
|
public static AgentScope start(
|
||||||
@Advice.Origin("#m") final String method,
|
@Advice.Origin("#m") final String method,
|
||||||
@Advice.This final RequestDispatcher dispatcher,
|
@Advice.This final RequestDispatcher dispatcher,
|
||||||
|
@Advice.Local("_requestSpan") Object requestSpan,
|
||||||
@Advice.Argument(0) final ServletRequest request) {
|
@Advice.Argument(0) final ServletRequest request) {
|
||||||
if (activeSpan() == null) {
|
if (activeSpan() == null) {
|
||||||
// Don't want to generate a new top-level span
|
// Don't want to generate a new top-level span
|
||||||
|
@ -87,8 +88,9 @@ public final class RequestDispatcherInstrumentation extends Instrumenter.Default
|
||||||
// In case we lose context, inject trace into to the request.
|
// In case we lose context, inject trace into to the request.
|
||||||
propagate().inject(span, request, SETTER);
|
propagate().inject(span, request, SETTER);
|
||||||
|
|
||||||
// temporarily remove from request to avoid spring resource name bubbling up:
|
// temporarily replace from request to avoid spring resource name bubbling up:
|
||||||
request.removeAttribute(DD_SPAN_ATTRIBUTE);
|
requestSpan = request.getAttribute(DD_SPAN_ATTRIBUTE);
|
||||||
|
request.setAttribute(DD_SPAN_ATTRIBUTE, span);
|
||||||
|
|
||||||
return activateSpan(span, true).setAsyncPropagation(true);
|
return activateSpan(span, true).setAsyncPropagation(true);
|
||||||
}
|
}
|
||||||
|
@ -96,14 +98,17 @@ public final class RequestDispatcherInstrumentation extends Instrumenter.Default
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stop(
|
public static void stop(
|
||||||
@Advice.Enter final AgentScope scope,
|
@Advice.Enter final AgentScope scope,
|
||||||
|
@Advice.Local("_requestSpan") final Object requestSpan,
|
||||||
@Advice.Argument(0) final ServletRequest request,
|
@Advice.Argument(0) final ServletRequest request,
|
||||||
@Advice.Thrown final Throwable throwable) {
|
@Advice.Thrown final Throwable throwable) {
|
||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now add it back...
|
if (requestSpan != null) {
|
||||||
request.setAttribute(DD_SPAN_ATTRIBUTE, scope.span());
|
// now add it back...
|
||||||
|
request.setAttribute(DD_SPAN_ATTRIBUTE, requestSpan);
|
||||||
|
}
|
||||||
|
|
||||||
DECORATE.onError(scope, throwable);
|
DECORATE.onError(scope, throwable);
|
||||||
DECORATE.beforeFinish(scope);
|
DECORATE.beforeFinish(scope);
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
|
import datadog.opentracing.DDSpan
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
|
|
||||||
import javax.servlet.ServletException
|
import javax.servlet.ServletException
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import javax.servlet.http.HttpServletResponse
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
|
import static datadog.opentracing.propagation.DatadogHttpCodec.SAMPLING_PRIORITY_KEY
|
||||||
|
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
|
||||||
|
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
|
||||||
|
import static datadog.trace.agent.decorator.HttpServerDecorator.DD_SPAN_ATTRIBUTE
|
||||||
import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
|
import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
|
||||||
import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
|
import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
|
||||||
|
|
||||||
class RequestDispatcherTest extends AgentTestRunner {
|
class RequestDispatcherTest extends AgentTestRunner {
|
||||||
|
|
||||||
def dispatcher = new RequestDispatcherUtils(Mock(HttpServletRequest), Mock(HttpServletResponse))
|
def request = Mock(HttpServletRequest)
|
||||||
|
def response = Mock(HttpServletResponse)
|
||||||
|
def mockSpan = Mock(DDSpan)
|
||||||
|
def dispatcher = new RequestDispatcherUtils(request, response)
|
||||||
|
|
||||||
def "test dispatch no-parent"() {
|
def "test dispatch no-parent"() {
|
||||||
when:
|
when:
|
||||||
|
@ -17,7 +25,17 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
dispatcher.include("")
|
dispatcher.include("")
|
||||||
|
|
||||||
then:
|
then:
|
||||||
assertTraces(0) {}
|
assertTraces(2) {
|
||||||
|
trace(0, 1) {
|
||||||
|
basicSpan(it, 0, "forward-child")
|
||||||
|
}
|
||||||
|
trace(1, 1) {
|
||||||
|
basicSpan(it, 0, "include-child")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
and:
|
||||||
|
0 * _
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test dispatcher #method with parent"() {
|
def "test dispatcher #method with parent"() {
|
||||||
|
@ -28,7 +46,7 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
|
|
||||||
then:
|
then:
|
||||||
assertTraces(1) {
|
assertTraces(1) {
|
||||||
trace(0, 2) {
|
trace(0, 3) {
|
||||||
basicSpan(it, 0, "parent")
|
basicSpan(it, 0, "parent")
|
||||||
span(1) {
|
span(1) {
|
||||||
operationName "servlet.$operation"
|
operationName "servlet.$operation"
|
||||||
|
@ -39,9 +57,22 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
defaultTags()
|
defaultTags()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
basicSpan(it, 2, "$operation-child", span(1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(TRACE_ID_KEY, _)
|
||||||
|
1 * request.setAttribute(SPAN_ID_KEY, _)
|
||||||
|
1 * request.setAttribute(SAMPLING_PRIORITY_KEY, _)
|
||||||
|
then:
|
||||||
|
1 * request.getAttribute(DD_SPAN_ATTRIBUTE) >> mockSpan
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(DD_SPAN_ATTRIBUTE, { it.spanName == "servlet.$operation" })
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(DD_SPAN_ATTRIBUTE, mockSpan)
|
||||||
|
0 * _
|
||||||
|
|
||||||
where:
|
where:
|
||||||
operation | method
|
operation | method
|
||||||
"forward" | "forward"
|
"forward" | "forward"
|
||||||
|
@ -55,7 +86,7 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
def "test dispatcher #method exception"() {
|
def "test dispatcher #method exception"() {
|
||||||
setup:
|
setup:
|
||||||
def ex = new ServletException("some error")
|
def ex = new ServletException("some error")
|
||||||
def dispatcher = new RequestDispatcherUtils(Mock(HttpServletRequest), Mock(HttpServletResponse), ex)
|
def dispatcher = new RequestDispatcherUtils(request, response, ex)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
runUnderTrace("parent") {
|
runUnderTrace("parent") {
|
||||||
|
@ -67,7 +98,7 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
th == ex
|
th == ex
|
||||||
|
|
||||||
assertTraces(1) {
|
assertTraces(1) {
|
||||||
trace(0, 2) {
|
trace(0, 3) {
|
||||||
basicSpan(it, 0, "parent", null, ex)
|
basicSpan(it, 0, "parent", null, ex)
|
||||||
span(1) {
|
span(1) {
|
||||||
operationName "servlet.$operation"
|
operationName "servlet.$operation"
|
||||||
|
@ -80,9 +111,22 @@ class RequestDispatcherTest extends AgentTestRunner {
|
||||||
errorTags(ex.class, ex.message)
|
errorTags(ex.class, ex.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
basicSpan(it, 2, "$operation-child", span(1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(TRACE_ID_KEY, _)
|
||||||
|
1 * request.setAttribute(SPAN_ID_KEY, _)
|
||||||
|
1 * request.setAttribute(SAMPLING_PRIORITY_KEY, _)
|
||||||
|
then:
|
||||||
|
1 * request.getAttribute(DD_SPAN_ATTRIBUTE) >> mockSpan
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(DD_SPAN_ATTRIBUTE, { it.spanName == "servlet.$operation" })
|
||||||
|
then:
|
||||||
|
1 * request.setAttribute(DD_SPAN_ATTRIBUTE, mockSpan)
|
||||||
|
0 * _
|
||||||
|
|
||||||
where:
|
where:
|
||||||
operation | method
|
operation | method
|
||||||
"forward" | "forward"
|
"forward" | "forward"
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -164,7 +167,15 @@ public class RequestDispatcherUtils {
|
||||||
class TestDispatcher implements RequestDispatcher {
|
class TestDispatcher implements RequestDispatcher {
|
||||||
@Override
|
@Override
|
||||||
public void forward(final ServletRequest servletRequest, final ServletResponse servletResponse)
|
public void forward(final ServletRequest servletRequest, final ServletResponse servletResponse)
|
||||||
throws ServletException, IOException {
|
throws ServletException {
|
||||||
|
runUnderTrace(
|
||||||
|
"forward-child",
|
||||||
|
new Callable<Object>() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (toThrow != null) {
|
if (toThrow != null) {
|
||||||
throw toThrow;
|
throw toThrow;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +183,15 @@ public class RequestDispatcherUtils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void include(final ServletRequest servletRequest, final ServletResponse servletResponse)
|
public void include(final ServletRequest servletRequest, final ServletResponse servletResponse)
|
||||||
throws ServletException, IOException {
|
throws ServletException {
|
||||||
|
runUnderTrace(
|
||||||
|
"include-child",
|
||||||
|
new Callable<Object>() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (toThrow != null) {
|
if (toThrow != null) {
|
||||||
throw toThrow;
|
throw toThrow;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue