From 29b9da5fb1f1fa528bacb12aebd83b60c2f65116 Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Fri, 24 Aug 2018 10:07:22 -0700 Subject: [PATCH 1/2] Add getRootSpan() to MutableSpan --- .../datadog/trace/api/interceptor/MutableSpan.java | 2 ++ .../src/main/java/datadog/opentracing/DDSpan.java | 5 +++++ .../groovy/datadog/opentracing/DDSpanTest.groovy | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/interceptor/MutableSpan.java b/dd-trace-api/src/main/java/datadog/trace/api/interceptor/MutableSpan.java index 458e89208f..3bce89d3f9 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/interceptor/MutableSpan.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/interceptor/MutableSpan.java @@ -41,4 +41,6 @@ public interface MutableSpan { Boolean isError(); MutableSpan setError(boolean value); + + MutableSpan getRootSpan(); } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java index 34b08e4930..e523b4ce7a 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java @@ -125,6 +125,11 @@ public class DDSpan implements Span, MutableSpan { return this; } + @Override + public MutableSpan getRootSpan() { + return context().getTrace().getRootSpan(); + } + public void setErrorMeta(final Throwable error) { setError(true); diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy index d228cfbee2..9abd211321 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy @@ -183,4 +183,18 @@ class DDSpanTest extends Specification { child2.getMetrics().get(DDSpanContext.PRIORITY_SAMPLING_KEY) == null child2.getMetrics().get(DDSpanContext.SAMPLE_RATE_KEY) == null } + + def "getRootSpan returns the root span"() { + setup: + def root = tracer.buildSpan("root").start() + def child = tracer.buildSpan("child").asChildOf(root).start() + + expect: + root.getRootSpan() == root + child.getRootSpan() == root + + cleanup: + child.finish() + root.finish() + } } From bc105af06f214ebde3378d628b462cd932697da1 Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Mon, 27 Aug 2018 11:33:21 -0700 Subject: [PATCH 2/2] Doc PendingTrace's root span. --- .../main/java/datadog/opentracing/PendingTrace.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java b/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java index 1ef8c7d770..f4c56319ad 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java @@ -40,6 +40,16 @@ public class PendingTrace extends ConcurrentLinkedDeque { Collections.newSetFromMap(new ConcurrentHashMap, Boolean>()); private final AtomicInteger pendingReferenceCount = new AtomicInteger(0); + /** + * During a trace there are cases where the root span must be accessed (e.g. priority sampling and + * trace-search tags). + * + *

Use a weak ref because we still need to handle buggy cases where the root span is not + * correctly closed (see SpanCleaner). + * + *

The root span will be available in non-buggy cases because it has either finished and + * strongly ref'd in this queue or is unfinished and ref'd in a ContinuableScope. + */ private final AtomicReference> rootSpan = new AtomicReference<>(); /** Ensure a trace is never written multiple times */