From 12c8524f4ab22f44a28328dac20647f3238cb366 Mon Sep 17 00:00:00 2001 From: Andrew Glaude Date: Fri, 10 Oct 2025 16:32:42 -0400 Subject: [PATCH 1/2] Add top_level to span debug output --- .../src/main/java/datadog/trace/core/DDSpanContext.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java b/dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java index 4c404ae0a38..30d6cf8c55f 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java @@ -1018,6 +1018,9 @@ public String toString() { if (measured) { s.append(" *measured*"); } + if (topLevel) { + s.append(" *top_level*"); + } synchronized (unsafeTags) { s.append(" tags=").append(new TreeMap<>(getTags())); From 922ebe32121f5200e8bd6c09f4fdde32209d27f4 Mon Sep 17 00:00:00 2001 From: Andrew Glaude Date: Fri, 10 Oct 2025 16:46:41 -0400 Subject: [PATCH 2/2] add test for top_level in output --- .../trace/core/DDSpanContextTest.groovy | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanContextTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanContextTest.groovy index 1cdaa33d668..22bc295d9b6 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanContextTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanContextTest.groovy @@ -312,6 +312,37 @@ class DDSpanContextTest extends DDCoreSpecification { context.toString().contains("id=-") == false } + def "toString includes top_level flag"() { + setup: + def parent = tracer.buildSpan("parentOperation") + .withServiceName("parentService") + .withResourceName("parentResource") + .start() + + // Child span with different service name should be top-level + def topLevelSpan = tracer.buildSpan("childOperation") + .withServiceName("childService") + .withResourceName("childResource") + .asChildOf(parent.context()) + .start() + + // Child span with same service name should not be top-level + def nonTopLevelSpan = tracer.buildSpan("childOperation2") + .withServiceName("parentService") + .withResourceName("childResource2") + .asChildOf(parent.context()) + .start() + + def topLevelContext = topLevelSpan.context() as DDSpanContext + def nonTopLevelContext = nonTopLevelSpan.context() as DDSpanContext + + expect: + topLevelContext.isTopLevel() == true + topLevelContext.toString().contains("*top_level*") == true + nonTopLevelContext.isTopLevel() == false + nonTopLevelContext.toString().contains("*top_level*") == false + } + static void assertTagmap(Map source, Map comparison, boolean removeThread = false) { def sourceWithoutCommonTags = new HashMap(source) sourceWithoutCommonTags.remove("runtime-id")