|
9 | 9 | import datadog.trace.api.gateway.Flow;
|
10 | 10 | import datadog.trace.bootstrap.instrumentation.api.AgentScope;
|
11 | 11 | import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
|
| 12 | +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; |
12 | 13 | import datadog.trace.bootstrap.instrumentation.api.Tags;
|
13 | 14 | import io.vertx.core.Handler;
|
14 | 15 | import io.vertx.ext.web.RoutingContext;
|
15 |
| -import org.slf4j.Logger; |
16 |
| -import org.slf4j.LoggerFactory; |
| 16 | +import io.vertx.ext.web.impl.RouteImpl; |
| 17 | +import io.vertx.ext.web.impl.RouterImpl; |
17 | 18 |
|
18 | 19 | public class RouteHandlerWrapper implements Handler<RoutingContext> {
|
19 |
| - private static final Logger log = LoggerFactory.getLogger(RouteHandlerWrapper.class); |
20 | 20 | static final String PARENT_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".parent";
|
21 | 21 | static final String HANDLER_SPAN_CONTEXT_KEY = AgentSpan.class.getName() + ".handler";
|
22 | 22 | static final String ROUTE_CONTEXT_KEY = "dd." + Tags.HTTP_ROUTE;
|
23 | 23 |
|
24 | 24 | private final Handler<RoutingContext> actual;
|
| 25 | + private final boolean spanStarter; |
25 | 26 |
|
26 | 27 | public RouteHandlerWrapper(final Handler<RoutingContext> handler) {
|
27 | 28 | actual = handler;
|
| 29 | + // When mounting a sub router, the handler is a lambda in either RouterImpl or RouteImpl, so |
| 30 | + // this skips that. This prevents routers from creating a span during handling. In the event |
| 31 | + // a route is not found, without this code, a span would be created for the router when it |
| 32 | + // shouldn't |
| 33 | + String name = handler.getClass().getName(); |
| 34 | + spanStarter = |
| 35 | + !(name.startsWith(RouterImpl.class.getName()) |
| 36 | + || name.startsWith(RouteImpl.class.getName())); |
28 | 37 | }
|
29 | 38 |
|
30 | 39 | @Override
|
31 | 40 | public void handle(final RoutingContext routingContext) {
|
32 | 41 | AgentSpan span = routingContext.get(HANDLER_SPAN_CONTEXT_KEY);
|
33 | 42 | Flow.Action.RequestBlockingAction rba = null;
|
34 |
| - if (span == null) { |
35 |
| - AgentSpan parentSpan = activeSpan(); |
36 |
| - routingContext.put(PARENT_SPAN_CONTEXT_KEY, parentSpan); |
| 43 | + if (spanStarter) { |
| 44 | + if (span == null) { |
| 45 | + AgentSpan parentSpan = activeSpan(); |
| 46 | + routingContext.put(PARENT_SPAN_CONTEXT_KEY, parentSpan); |
37 | 47 |
|
38 |
| - span = startSpan(INSTRUMENTATION_NAME); |
39 |
| - routingContext.put(HANDLER_SPAN_CONTEXT_KEY, span); |
| 48 | + span = startSpan(INSTRUMENTATION_NAME); |
| 49 | + routingContext.put(HANDLER_SPAN_CONTEXT_KEY, span); |
40 | 50 |
|
41 |
| - routingContext.response().endHandler(new EndHandlerWrapper(routingContext)); |
42 |
| - DECORATE.afterStart(span); |
43 |
| - span.setResourceName(DECORATE.className(actual.getClass())); |
44 |
| - } |
45 |
| - |
46 |
| - updateRoutingContextWithRoute(routingContext); |
| 51 | + routingContext.response().endHandler(new EndHandlerWrapper(routingContext)); |
| 52 | + DECORATE.afterStart(span); |
| 53 | + span.setResourceName(DECORATE.className(actual.getClass())); |
| 54 | + } |
47 | 55 |
|
48 |
| - try (final AgentScope scope = activateSpan(span)) { |
| 56 | + updateRoutingContextWithRoute(routingContext); |
| 57 | + } |
| 58 | + try (final AgentScope scope = |
| 59 | + span != null ? activateSpan(span) : AgentTracer.NoopAgentScope.INSTANCE) { |
49 | 60 | scope.setAsyncPropagation(true);
|
50 | 61 | try {
|
51 | 62 | actual.handle(routingContext);
|
|
0 commit comments