From ccdfd7be0b3f1f75edb7bc6fea539dd77669e35f Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Mon, 17 Nov 2025 15:55:20 -0500 Subject: [PATCH 01/10] Extracting static helper --- .../src/main/java/datadog/trace/core/CoreTracer.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 05c213a9c18..d71eee7c41c 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1554,7 +1554,17 @@ public final CoreSpanBuilder ignoreActiveSpan() { } protected final DDSpan buildSpan() { - DDSpan span = DDSpan.create(instrumentationName, timestampMicro, buildSpanContext(), links); + return buildSpan(tracer, instrumentationName, timestampMicro, links, buildSpanContext()); + } + + protected static final DDSpan buildSpan( + CoreTracer tracer, + String instrumentationName, + long timestampMicro, + List links, + DDSpanContext spanContext) + { + DDSpan span = DDSpan.create(instrumentationName, timestampMicro, spanContext, links); if (span.isLocalRootSpan()) { EndpointTracker tracker = tracer.onRootSpanStarted(span); if (tracker != null) { From c60e9be1433f66b9a831fd0eef423dad1d070fc6 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 09:22:57 -0500 Subject: [PATCH 02/10] Extract static version of buildSpanContext --- .../java/datadog/trace/core/CoreTracer.java | 96 +++++++++++++++---- 1 file changed, 75 insertions(+), 21 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index d71eee7c41c..f1eece1adb4 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1574,7 +1574,9 @@ protected static final DDSpan buildSpan( return span; } - private final void addParentContextAsLinks(AgentSpanContext parentContext) { + private static final List addParentContextLink( + List links, + AgentSpanContext parentContext) { SpanLink link; if (parentContext instanceof ExtractedContext) { String headers = ((ExtractedContext) parentContext).getPropagationStyle().toString(); @@ -1587,20 +1589,42 @@ private final void addParentContextAsLinks(AgentSpanContext parentContext) { } else { link = SpanLink.from(parentContext); } - withLink(link); + return addLink(links, link); } - private final void addTerminatedContextAsLinks() { - if (this.parent instanceof TagContext) { + protected static final List addTerminatedContextAsLinks( + List links, + AgentSpanContext parentContext) + { + if (parentContext instanceof TagContext) { List terminatedContextLinks = - ((TagContext) this.parent).getTerminatedContextLinks(); + ((TagContext) parentContext).getTerminatedContextLinks(); if (!terminatedContextLinks.isEmpty()) { - if (this.links == null) { - this.links = new ArrayList<>(); - } - this.links.addAll(terminatedContextLinks); + return addLinks(links, terminatedContextLinks); } } + return links; + } + + protected static final List addLink( + List links, + AgentSpanLink link) + { + if ( links == null ) links = new ArrayList<>(); + links.add(link); + return links; + } + + protected static final List addLinks( + List links, + List additionalLinks) + { + if ( links == null ) { + links = new ArrayList<>(additionalLinks); + } else { + links.addAll(additionalLinks); + } + return links; } @Override @@ -1744,9 +1768,41 @@ public final CoreSpanBuilder withSpanId(final long spanId) { * @return the context */ private final DDSpanContext buildSpanContext() { - final DDTraceId traceId; - final long spanId; - final long parentSpanId; + return this.buildSpanContext( + this.tracer, + this.spanId, + this.serviceName, + this.operationName, + this.resourceName, + this.parent, + this.ignoreScope, + this.errorFlag, + this.spanType, + this.tagLedger, + this.links, + this.builderRequestContextDataAppSec, + this.builderRequestContextDataIast, + this.builderCiVisibilityContextData); + } + + protected static final DDSpanContext buildSpanContext( + final CoreTracer tracer, + long spanId, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) + { + DDTraceId traceId; + long parentSpanId; final Map baggage; final Baggage w3cBaggage; final TraceCollector parentTraceCollector; @@ -1762,15 +1818,13 @@ private final DDSpanContext buildSpanContext() { Object ciVisibilityContextData; final PathwayContext pathwayContext; final PropagationTags propagationTags; - - if (this.spanId == 0) { + + if (spanId == 0) { spanId = tracer.idGenerationStrategy.generateSpanId(); - } else { - spanId = this.spanId; } // Find the parent context - AgentSpanContext parentContext = parent; + AgentSpanContext parentContext = incomingParentContext; if (parentContext == null && !ignoreScope) { // use the Scope as parent unless overridden or ignored. final AgentSpan activeSpan = tracer.scopeManager.activeSpan(); @@ -1778,11 +1832,12 @@ private final DDSpanContext buildSpanContext() { parentContext = activeSpan.context(); } } + // Handle remote terminated context as span links if (parentContext != null && parentContext.isRemote()) { switch (Config.get().getTracePropagationBehaviorExtract()) { case RESTART: - addParentContextAsLinks(parentContext); + links = addParentContextLink(links, parentContext); parentContext = null; break; case IGNORE: @@ -1790,7 +1845,7 @@ private final DDSpanContext buildSpanContext() { break; case CONTINUE: default: - addTerminatedContextAsLinks(); + links = addTerminatedContextAsLinks(links, incomingParentContext); } } @@ -1930,8 +1985,7 @@ private final DDSpanContext buildSpanContext() { serviceName = tracer.serviceName; } - final CharSequence operationName = - this.operationName != null ? this.operationName : resourceName; + if ( operationName == null ) operationName = resourceName; final TagMap mergedTracerTags = traceConfig.mergedTracerTags; boolean mergedTracerTagsNeedsIntercept = traceConfig.mergedTracerTagsNeedsIntercept; From 89ff968b82070ac9a3ea006ee061985fb0a92f89 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 10:29:27 -0500 Subject: [PATCH 03/10] Switch to singleSpanBuilder --- dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index f1eece1adb4..3ce41d6b8fd 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1109,7 +1109,7 @@ public AgentSpan startSpan( final CharSequence spanName, final AgentSpanContext parent, final long startTimeMicros) { - return buildSpan(instrumentationName, spanName) + return singleSpanBuilder(instrumentationName, spanName) .ignoreActiveSpan() .asChildOf(parent) .withStartTimestamp(startTimeMicros) From 4d345eaacf1c43f5ce142b0e6d0a161650c65021 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 10:52:30 -0500 Subject: [PATCH 04/10] Extracting static version of startSpan --- .../java/datadog/trace/core/CoreTracer.java | 77 ++++++++++++++++++- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 3ce41d6b8fd..52c7c785383 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1553,10 +1553,33 @@ public final CoreSpanBuilder ignoreActiveSpan() { return this; } + @Deprecated protected final DDSpan buildSpan() { return buildSpan(tracer, instrumentationName, timestampMicro, links, buildSpanContext()); } + protected static final DDSpan buildSpan( + final CoreTracer tracer, + long spanId, + String instrumentationName, + long timestampMicro, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) + { + return buildSpan(tracer, instrumentationName, timestampMicro, links, + buildSpanContext(tracer, spanId, serviceName, operationName, resourceName, incomingParentContext, ignoreScope, errorFlag, spanType, tagLedger, links, builderRequestContextDataAppSec, builderRequestContextDataIast, builderCiVisibilityContextData)); + } + protected static final DDSpan buildSpan( CoreTracer tracer, String instrumentationName, @@ -1625,11 +1648,11 @@ protected static final List addLinks( links.addAll(additionalLinks); } return links; - } + } @Override - public abstract AgentSpan start(); - + public abstract AgentSpan start(); + protected AgentSpan startImpl() { AgentSpanContext pc = parent; if (pc == null && !ignoreScope) { @@ -1645,6 +1668,54 @@ protected AgentSpan startImpl() { return buildSpan(); } + protected static final AgentSpan startSpan( + final CoreTracer tracer, + long spanId, + String instrumentationName, + long timestampMicro, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) + { + AgentSpanContext pc = incomingParentContext; + if (pc == null && !ignoreScope) { + final AgentSpan span = tracer.activeSpan(); + if (span != null) { + pc = span.context(); + } + } + + if (pc == BlackHoleSpan.Context.INSTANCE) { + return new BlackHoleSpan(pc.getTraceId()); + } + return buildSpan( + tracer, + spanId, + instrumentationName, + timestampMicro, + serviceName, + operationName, + resourceName, + incomingParentContext, + ignoreScope, + errorFlag, + spanType, + tagLedger, + links, + builderRequestContextDataAppSec, + builderRequestContextDataIast, + builderCiVisibilityContextData); + } + @Override public final CoreSpanBuilder withTag(final String tag, final Number number) { return withTag(tag, (Object) number); From 8f50da6e34c27f7d24915b6fd377b7e9df1cc356 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 10:53:42 -0500 Subject: [PATCH 05/10] spotless --- .../java/datadog/trace/core/CoreTracer.java | 235 +++++++++--------- 1 file changed, 121 insertions(+), 114 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 52c7c785383..c23e893606e 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1557,36 +1557,52 @@ public final CoreSpanBuilder ignoreActiveSpan() { protected final DDSpan buildSpan() { return buildSpan(tracer, instrumentationName, timestampMicro, links, buildSpanContext()); } - + protected static final DDSpan buildSpan( - final CoreTracer tracer, - long spanId, - String instrumentationName, - long timestampMicro, - String serviceName, - CharSequence operationName, - String resourceName, - AgentSpanContext incomingParentContext, - boolean ignoreScope, - boolean errorFlag, - CharSequence spanType, - TagMap.Ledger tagLedger, - List links, - Object builderRequestContextDataAppSec, - Object builderRequestContextDataIast, - Object builderCiVisibilityContextData) - { - return buildSpan(tracer, instrumentationName, timestampMicro, links, - buildSpanContext(tracer, spanId, serviceName, operationName, resourceName, incomingParentContext, ignoreScope, errorFlag, spanType, tagLedger, links, builderRequestContextDataAppSec, builderRequestContextDataIast, builderCiVisibilityContextData)); - } - + final CoreTracer tracer, + long spanId, + String instrumentationName, + long timestampMicro, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) { + return buildSpan( + tracer, + instrumentationName, + timestampMicro, + links, + buildSpanContext( + tracer, + spanId, + serviceName, + operationName, + resourceName, + incomingParentContext, + ignoreScope, + errorFlag, + spanType, + tagLedger, + links, + builderRequestContextDataAppSec, + builderRequestContextDataIast, + builderCiVisibilityContextData)); + } + protected static final DDSpan buildSpan( - CoreTracer tracer, - String instrumentationName, - long timestampMicro, - List links, - DDSpanContext spanContext) - { + CoreTracer tracer, + String instrumentationName, + long timestampMicro, + List links, + DDSpanContext spanContext) { DDSpan span = DDSpan.create(instrumentationName, timestampMicro, spanContext, links); if (span.isLocalRootSpan()) { EndpointTracker tracker = tracer.onRootSpanStarted(span); @@ -1598,8 +1614,7 @@ protected static final DDSpan buildSpan( } private static final List addParentContextLink( - List links, - AgentSpanContext parentContext) { + List links, AgentSpanContext parentContext) { SpanLink link; if (parentContext instanceof ExtractedContext) { String headers = ((ExtractedContext) parentContext).getPropagationStyle().toString(); @@ -1616,9 +1631,7 @@ private static final List addParentContextLink( } protected static final List addTerminatedContextAsLinks( - List links, - AgentSpanContext parentContext) - { + List links, AgentSpanContext parentContext) { if (parentContext instanceof TagContext) { List terminatedContextLinks = ((TagContext) parentContext).getTerminatedContextLinks(); @@ -1628,31 +1641,27 @@ protected static final List addTerminatedContextAsLinks( } return links; } - + protected static final List addLink( - List links, - AgentSpanLink link) - { - if ( links == null ) links = new ArrayList<>(); + List links, AgentSpanLink link) { + if (links == null) links = new ArrayList<>(); links.add(link); return links; } protected static final List addLinks( - List links, - List additionalLinks) - { - if ( links == null ) { - links = new ArrayList<>(additionalLinks); + List links, List additionalLinks) { + if (links == null) { + links = new ArrayList<>(additionalLinks); } else { - links.addAll(additionalLinks); + links.addAll(additionalLinks); } return links; - } + } @Override - public abstract AgentSpan start(); - + public abstract AgentSpan start(); + protected AgentSpan startImpl() { AgentSpanContext pc = parent; if (pc == null && !ignoreScope) { @@ -1669,23 +1678,22 @@ protected AgentSpan startImpl() { } protected static final AgentSpan startSpan( - final CoreTracer tracer, - long spanId, - String instrumentationName, - long timestampMicro, - String serviceName, - CharSequence operationName, - String resourceName, - AgentSpanContext incomingParentContext, - boolean ignoreScope, - boolean errorFlag, - CharSequence spanType, - TagMap.Ledger tagLedger, - List links, - Object builderRequestContextDataAppSec, - Object builderRequestContextDataIast, - Object builderCiVisibilityContextData) - { + final CoreTracer tracer, + long spanId, + String instrumentationName, + long timestampMicro, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) { AgentSpanContext pc = incomingParentContext; if (pc == null && !ignoreScope) { final AgentSpan span = tracer.activeSpan(); @@ -1698,22 +1706,22 @@ protected static final AgentSpan startSpan( return new BlackHoleSpan(pc.getTraceId()); } return buildSpan( - tracer, - spanId, - instrumentationName, - timestampMicro, - serviceName, - operationName, - resourceName, - incomingParentContext, - ignoreScope, - errorFlag, - spanType, - tagLedger, - links, - builderRequestContextDataAppSec, - builderRequestContextDataIast, - builderCiVisibilityContextData); + tracer, + spanId, + instrumentationName, + timestampMicro, + serviceName, + operationName, + resourceName, + incomingParentContext, + ignoreScope, + errorFlag, + spanType, + tagLedger, + links, + builderRequestContextDataAppSec, + builderRequestContextDataIast, + builderCiVisibilityContextData); } @Override @@ -1840,38 +1848,37 @@ public final CoreSpanBuilder withSpanId(final long spanId) { */ private final DDSpanContext buildSpanContext() { return this.buildSpanContext( - this.tracer, - this.spanId, - this.serviceName, - this.operationName, - this.resourceName, - this.parent, - this.ignoreScope, - this.errorFlag, - this.spanType, - this.tagLedger, - this.links, - this.builderRequestContextDataAppSec, - this.builderRequestContextDataIast, - this.builderCiVisibilityContextData); - } - + this.tracer, + this.spanId, + this.serviceName, + this.operationName, + this.resourceName, + this.parent, + this.ignoreScope, + this.errorFlag, + this.spanType, + this.tagLedger, + this.links, + this.builderRequestContextDataAppSec, + this.builderRequestContextDataIast, + this.builderCiVisibilityContextData); + } + protected static final DDSpanContext buildSpanContext( - final CoreTracer tracer, - long spanId, - String serviceName, - CharSequence operationName, - String resourceName, - AgentSpanContext incomingParentContext, - boolean ignoreScope, - boolean errorFlag, - CharSequence spanType, - TagMap.Ledger tagLedger, - List links, - Object builderRequestContextDataAppSec, - Object builderRequestContextDataIast, - Object builderCiVisibilityContextData) - { + final CoreTracer tracer, + long spanId, + String serviceName, + CharSequence operationName, + String resourceName, + AgentSpanContext incomingParentContext, + boolean ignoreScope, + boolean errorFlag, + CharSequence spanType, + TagMap.Ledger tagLedger, + List links, + Object builderRequestContextDataAppSec, + Object builderRequestContextDataIast, + Object builderCiVisibilityContextData) { DDTraceId traceId; long parentSpanId; final Map baggage; @@ -1889,7 +1896,7 @@ protected static final DDSpanContext buildSpanContext( Object ciVisibilityContextData; final PathwayContext pathwayContext; final PropagationTags propagationTags; - + if (spanId == 0) { spanId = tracer.idGenerationStrategy.generateSpanId(); } @@ -1903,7 +1910,7 @@ protected static final DDSpanContext buildSpanContext( parentContext = activeSpan.context(); } } - + // Handle remote terminated context as span links if (parentContext != null && parentContext.isRemote()) { switch (Config.get().getTracePropagationBehaviorExtract()) { @@ -2056,7 +2063,7 @@ protected static final DDSpanContext buildSpanContext( serviceName = tracer.serviceName; } - if ( operationName == null ) operationName = resourceName; + if (operationName == null) operationName = resourceName; final TagMap mergedTracerTags = traceConfig.mergedTracerTags; boolean mergedTracerTagsNeedsIntercept = traceConfig.mergedTracerTagsNeedsIntercept; From 10628b0ab6688314a07d201e484119e363a5f8a2 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 14:57:59 -0500 Subject: [PATCH 06/10] Reorganizing link & parent resolution Previous static extraction caused a test to fail because links logic relied on having a side effect on the builder instance's List --- .../java/datadog/trace/core/CoreTracer.java | 225 +++++++++--------- 1 file changed, 113 insertions(+), 112 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index c23e893606e..57c7c8053bb 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1083,24 +1083,19 @@ static final ReusableSingleSpanBuilder reuseSingleSpanBuilder( @Override public AgentSpan startSpan(final String instrumentationName, final CharSequence spanName) { - return singleSpanBuilder(instrumentationName, spanName).start(); + return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, null, false, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); } @Override public AgentSpan startSpan( final String instrumentationName, final CharSequence spanName, final long startTimeMicros) { - return singleSpanBuilder(instrumentationName, spanName) - .withStartTimestamp(startTimeMicros) - .start(); + return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, null, false, startTimeMicros); } @Override public AgentSpan startSpan( String instrumentationName, final CharSequence spanName, final AgentSpanContext parent) { - return singleSpanBuilder(instrumentationName, spanName) - .ignoreActiveSpan() - .asChildOf(parent) - .start(); + return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, parent, true, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); } @Override @@ -1108,12 +1103,9 @@ public AgentSpan startSpan( final String instrumentationName, final CharSequence spanName, final AgentSpanContext parent, - final long startTimeMicros) { - return singleSpanBuilder(instrumentationName, spanName) - .ignoreActiveSpan() - .asChildOf(parent) - .withStartTimestamp(startTimeMicros) - .start(); + final long startTimeMicros) + { + return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, parent, true, startTimeMicros); } @Override @@ -1521,6 +1513,10 @@ private static Map invertMap(Map map) { /** Spans are built using this builder */ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder { + protected static final boolean IGNORE_SCOPE_DEFAULT = false; + protected static final int SPAN_ID_DEFAULT = 0; + protected static final long DEFAULT_TIMESTAMP_MICRO = 0L; + protected final CoreTracer tracer; protected String instrumentationName; @@ -1535,12 +1531,12 @@ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder protected String resourceName; protected boolean errorFlag; protected CharSequence spanType; - protected boolean ignoreScope = false; + protected boolean ignoreScope = IGNORE_SCOPE_DEFAULT; protected Object builderRequestContextDataAppSec; protected Object builderRequestContextDataIast; protected Object builderCiVisibilityContextData; protected List links; - protected long spanId; + protected long spanId = SPAN_ID_DEFAULT; // Make sure any fields added here are also reset properly in ReusableSingleSpanBuilder.reset CoreSpanBuilder(CoreTracer tracer) { @@ -1553,11 +1549,6 @@ public final CoreSpanBuilder ignoreActiveSpan() { return this; } - @Deprecated - protected final DDSpan buildSpan() { - return buildSpan(tracer, instrumentationName, timestampMicro, links, buildSpanContext()); - } - protected static final DDSpan buildSpan( final CoreTracer tracer, long spanId, @@ -1566,7 +1557,7 @@ protected static final DDSpan buildSpan( String serviceName, CharSequence operationName, String resourceName, - AgentSpanContext incomingParentContext, + AgentSpanContext resolvedParentContext, boolean ignoreScope, boolean errorFlag, CharSequence spanType, @@ -1575,7 +1566,7 @@ protected static final DDSpan buildSpan( Object builderRequestContextDataAppSec, Object builderRequestContextDataIast, Object builderCiVisibilityContextData) { - return buildSpan( + return buildSpanImpl( tracer, instrumentationName, timestampMicro, @@ -1586,8 +1577,7 @@ protected static final DDSpan buildSpan( serviceName, operationName, resourceName, - incomingParentContext, - ignoreScope, + resolvedParentContext, errorFlag, spanType, tagLedger, @@ -1597,7 +1587,7 @@ protected static final DDSpan buildSpan( builderCiVisibilityContextData)); } - protected static final DDSpan buildSpan( + protected static final DDSpan buildSpanImpl( CoreTracer tracer, String instrumentationName, long timestampMicro, @@ -1663,19 +1653,52 @@ protected static final List addLinks( public abstract AgentSpan start(); protected AgentSpan startImpl() { - AgentSpanContext pc = parent; - if (pc == null && !ignoreScope) { - final AgentSpan span = tracer.activeSpan(); - if (span != null) { - pc = span.context(); - } - } - - if (pc == BlackHoleSpan.Context.INSTANCE) { - return new BlackHoleSpan(pc.getTraceId()); - } - return buildSpan(); + return startSpan( + this.tracer, + this.spanId, + this.instrumentationName, + this.timestampMicro, + this.serviceName, + this.operationName, + this.resourceName, + this.parent, + this.ignoreScope, + this.errorFlag, + this.spanType, + this.tagLedger, + this.links, + this.builderRequestContextDataAppSec, + this.builderRequestContextDataIast, + this.builderCiVisibilityContextData); + } + + protected static final AgentSpan startSpan( + final CoreTracer tracer, + String instrumentationName, + CharSequence operationName, + AgentSpanContext specifiedParentContext, + boolean ignoreScope, + long timestampMicros) + { + return startSpan( + tracer, + SPAN_ID_DEFAULT, + instrumentationName, + timestampMicros, + null /* serviceName */, + operationName, + null /* resourceName */, + specifiedParentContext, + ignoreScope, + false /* errorFlag */, + null /* spanType */, + null /* tagLedger */, + null /* links */, + null /* appSec */, + null /* iast */, + null /* ciViz */); } + protected static final AgentSpan startSpan( final CoreTracer tracer, @@ -1685,7 +1708,7 @@ protected static final AgentSpan startSpan( String serviceName, CharSequence operationName, String resourceName, - AgentSpanContext incomingParentContext, + AgentSpanContext specifiedParentContext, boolean ignoreScope, boolean errorFlag, CharSequence spanType, @@ -1693,18 +1716,41 @@ protected static final AgentSpan startSpan( List links, Object builderRequestContextDataAppSec, Object builderRequestContextDataIast, - Object builderCiVisibilityContextData) { - AgentSpanContext pc = incomingParentContext; - if (pc == null && !ignoreScope) { - final AgentSpan span = tracer.activeSpan(); - if (span != null) { - pc = span.context(); + Object builderCiVisibilityContextData) + { + // Find the parent context + AgentSpanContext parentContext = specifiedParentContext; + if (parentContext == null && !ignoreScope) { + // use the Scope as parent unless overridden or ignored. + final AgentSpan activeSpan = tracer.scopeManager.activeSpan(); + if (activeSpan != null) { + parentContext = activeSpan.context(); + } + } + + if (parentContext == BlackHoleSpan.Context.INSTANCE) { + return new BlackHoleSpan(parentContext.getTraceId()); + } + + // Handle remote terminated context as span links + if (parentContext != null && parentContext.isRemote()) { + switch (Config.get().getTracePropagationBehaviorExtract()) { + case RESTART: + links = addParentContextLink(links, parentContext); + parentContext = null; + break; + + case IGNORE: + parentContext = null; + break; + + case CONTINUE: + default: + links = addTerminatedContextAsLinks(links, specifiedParentContext); + break; } } - - if (pc == BlackHoleSpan.Context.INSTANCE) { - return new BlackHoleSpan(pc.getTraceId()); - } + return buildSpan( tracer, spanId, @@ -1713,7 +1759,7 @@ protected static final AgentSpan startSpan( serviceName, operationName, resourceName, - incomingParentContext, + parentContext, ignoreScope, errorFlag, spanType, @@ -1846,32 +1892,13 @@ public final CoreSpanBuilder withSpanId(final long spanId) { * * @return the context */ - private final DDSpanContext buildSpanContext() { - return this.buildSpanContext( - this.tracer, - this.spanId, - this.serviceName, - this.operationName, - this.resourceName, - this.parent, - this.ignoreScope, - this.errorFlag, - this.spanType, - this.tagLedger, - this.links, - this.builderRequestContextDataAppSec, - this.builderRequestContextDataIast, - this.builderCiVisibilityContextData); - } - protected static final DDSpanContext buildSpanContext( final CoreTracer tracer, long spanId, String serviceName, CharSequence operationName, String resourceName, - AgentSpanContext incomingParentContext, - boolean ignoreScope, + AgentSpanContext resolvedParentContext, boolean errorFlag, CharSequence spanType, TagMap.Ledger tagLedger, @@ -1901,38 +1928,12 @@ protected static final DDSpanContext buildSpanContext( spanId = tracer.idGenerationStrategy.generateSpanId(); } - // Find the parent context - AgentSpanContext parentContext = incomingParentContext; - if (parentContext == null && !ignoreScope) { - // use the Scope as parent unless overridden or ignored. - final AgentSpan activeSpan = tracer.scopeManager.activeSpan(); - if (activeSpan != null) { - parentContext = activeSpan.context(); - } - } - - // Handle remote terminated context as span links - if (parentContext != null && parentContext.isRemote()) { - switch (Config.get().getTracePropagationBehaviorExtract()) { - case RESTART: - links = addParentContextLink(links, parentContext); - parentContext = null; - break; - case IGNORE: - parentContext = null; - break; - case CONTINUE: - default: - links = addTerminatedContextAsLinks(links, incomingParentContext); - } - } - String parentServiceName = null; // Propagate internal trace. // Note: if we are not in the context of distributed tracing, and we are starting the first // root span, parentContext will be null at this point. - if (parentContext instanceof DDSpanContext) { - final DDSpanContext ddsc = (DDSpanContext) parentContext; + if (resolvedParentContext instanceof DDSpanContext) { + final DDSpanContext ddsc = (DDSpanContext) resolvedParentContext; traceId = ddsc.getTraceId(); parentSpanId = ddsc.getSpanId(); baggage = ddsc.getBaggageItems(); @@ -1948,7 +1949,7 @@ protected static final DDSpanContext buildSpanContext( if (serviceName == null) { serviceName = parentServiceName; } - RequestContext requestContext = ((DDSpanContext) parentContext).getRequestContext(); + RequestContext requestContext = ((DDSpanContext) resolvedParentContext).getRequestContext(); if (requestContext != null) { requestContextDataAppSec = requestContext.getData(RequestContextSlot.APPSEC); requestContextDataIast = requestContext.getData(RequestContextSlot.IAST); @@ -1962,21 +1963,21 @@ protected static final DDSpanContext buildSpanContext( } else { long endToEndStartTime; - if (parentContext instanceof ExtractedContext) { + if (resolvedParentContext instanceof ExtractedContext) { // Propagate external trace - final ExtractedContext extractedContext = (ExtractedContext) parentContext; + final ExtractedContext extractedContext = (ExtractedContext) resolvedParentContext; traceId = extractedContext.getTraceId(); parentSpanId = extractedContext.getSpanId(); samplingPriority = extractedContext.getSamplingPriority(); endToEndStartTime = extractedContext.getEndToEndStartTime(); propagationTags = extractedContext.getPropagationTags(); - } else if (parentContext != null) { + } else if (resolvedParentContext != null) { traceId = - parentContext.getTraceId() == DDTraceId.ZERO + resolvedParentContext.getTraceId() == DDTraceId.ZERO ? tracer.idGenerationStrategy.generateTraceId() - : parentContext.getTraceId(); - parentSpanId = parentContext.getSpanId(); - samplingPriority = parentContext.getSamplingPriority(); + : resolvedParentContext.getTraceId(); + parentSpanId = resolvedParentContext.getSpanId(); + samplingPriority = resolvedParentContext.getSamplingPriority(); endToEndStartTime = 0; propagationTags = tracer.propagationTagsFactory.empty(); } else { @@ -1991,8 +1992,8 @@ protected static final DDSpanContext buildSpanContext( ConfigSnapshot traceConfig; // Get header tags and set origin whether propagating or not. - if (parentContext instanceof TagContext) { - TagContext tc = (TagContext) parentContext; + if (resolvedParentContext instanceof TagContext) { + TagContext tc = (TagContext) resolvedParentContext; traceConfig = (ConfigSnapshot) tc.getTraceConfig(); coreTags = tc.getTags(); coreTagsNeedsIntercept = true; // maybe intercept isn't needed? @@ -2028,10 +2029,10 @@ protected static final DDSpanContext buildSpanContext( // Use parent pathwayContext if present and started pathwayContext = - parentContext != null - && parentContext.getPathwayContext() != null - && parentContext.getPathwayContext().isStarted() - ? parentContext.getPathwayContext() + resolvedParentContext != null + && resolvedParentContext.getPathwayContext() != null + && resolvedParentContext.getPathwayContext().isStarted() + ? resolvedParentContext.getPathwayContext() : tracer.dataStreamsMonitoring.newPathwayContext(); // when removing fake services the best upward service name to pick is the local root one From 1a311015c56b06ae35d64c36b64506119100135a Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 18 Nov 2025 16:36:25 -0500 Subject: [PATCH 07/10] spotless --- .../java/datadog/trace/core/CoreTracer.java | 110 +++++++++--------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 57c7c8053bb..08db9c6205f 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1083,19 +1083,22 @@ static final ReusableSingleSpanBuilder reuseSingleSpanBuilder( @Override public AgentSpan startSpan(final String instrumentationName, final CharSequence spanName) { - return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, null, false, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); + return CoreSpanBuilder.startSpan( + this, instrumentationName, spanName, null, false, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); } @Override public AgentSpan startSpan( final String instrumentationName, final CharSequence spanName, final long startTimeMicros) { - return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, null, false, startTimeMicros); + return CoreSpanBuilder.startSpan( + this, instrumentationName, spanName, null, false, startTimeMicros); } @Override public AgentSpan startSpan( String instrumentationName, final CharSequence spanName, final AgentSpanContext parent) { - return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, parent, true, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); + return CoreSpanBuilder.startSpan( + this, instrumentationName, spanName, parent, true, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); } @Override @@ -1103,9 +1106,9 @@ public AgentSpan startSpan( final String instrumentationName, final CharSequence spanName, final AgentSpanContext parent, - final long startTimeMicros) - { - return CoreSpanBuilder.startSpan(this, instrumentationName, spanName, parent, true, startTimeMicros); + final long startTimeMicros) { + return CoreSpanBuilder.startSpan( + this, instrumentationName, spanName, parent, true, startTimeMicros); } @Override @@ -1513,10 +1516,10 @@ private static Map invertMap(Map map) { /** Spans are built using this builder */ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder { - protected static final boolean IGNORE_SCOPE_DEFAULT = false; - protected static final int SPAN_ID_DEFAULT = 0; - protected static final long DEFAULT_TIMESTAMP_MICRO = 0L; - + protected static final boolean IGNORE_SCOPE_DEFAULT = false; + protected static final int SPAN_ID_DEFAULT = 0; + protected static final long DEFAULT_TIMESTAMP_MICRO = 0L; + protected final CoreTracer tracer; protected String instrumentationName; @@ -1654,33 +1657,32 @@ protected static final List addLinks( protected AgentSpan startImpl() { return startSpan( - this.tracer, - this.spanId, - this.instrumentationName, - this.timestampMicro, - this.serviceName, - this.operationName, - this.resourceName, - this.parent, - this.ignoreScope, - this.errorFlag, - this.spanType, - this.tagLedger, - this.links, - this.builderRequestContextDataAppSec, - this.builderRequestContextDataIast, - this.builderCiVisibilityContextData); - } - + this.tracer, + this.spanId, + this.instrumentationName, + this.timestampMicro, + this.serviceName, + this.operationName, + this.resourceName, + this.parent, + this.ignoreScope, + this.errorFlag, + this.spanType, + this.tagLedger, + this.links, + this.builderRequestContextDataAppSec, + this.builderRequestContextDataIast, + this.builderCiVisibilityContextData); + } + protected static final AgentSpan startSpan( - final CoreTracer tracer, - String instrumentationName, - CharSequence operationName, - AgentSpanContext specifiedParentContext, - boolean ignoreScope, - long timestampMicros) - { - return startSpan( + final CoreTracer tracer, + String instrumentationName, + CharSequence operationName, + AgentSpanContext specifiedParentContext, + boolean ignoreScope, + long timestampMicros) { + return startSpan( tracer, SPAN_ID_DEFAULT, instrumentationName, @@ -1698,7 +1700,6 @@ protected static final AgentSpan startSpan( null /* iast */, null /* ciViz */); } - protected static final AgentSpan startSpan( final CoreTracer tracer, @@ -1716,22 +1717,21 @@ protected static final AgentSpan startSpan( List links, Object builderRequestContextDataAppSec, Object builderRequestContextDataIast, - Object builderCiVisibilityContextData) - { - // Find the parent context - AgentSpanContext parentContext = specifiedParentContext; - if (parentContext == null && !ignoreScope) { - // use the Scope as parent unless overridden or ignored. - final AgentSpan activeSpan = tracer.scopeManager.activeSpan(); - if (activeSpan != null) { - parentContext = activeSpan.context(); - } - } - - if (parentContext == BlackHoleSpan.Context.INSTANCE) { - return new BlackHoleSpan(parentContext.getTraceId()); + Object builderCiVisibilityContextData) { + // Find the parent context + AgentSpanContext parentContext = specifiedParentContext; + if (parentContext == null && !ignoreScope) { + // use the Scope as parent unless overridden or ignored. + final AgentSpan activeSpan = tracer.scopeManager.activeSpan(); + if (activeSpan != null) { + parentContext = activeSpan.context(); } - + } + + if (parentContext == BlackHoleSpan.Context.INSTANCE) { + return new BlackHoleSpan(parentContext.getTraceId()); + } + // Handle remote terminated context as span links if (parentContext != null && parentContext.isRemote()) { switch (Config.get().getTracePropagationBehaviorExtract()) { @@ -1739,18 +1739,18 @@ protected static final AgentSpan startSpan( links = addParentContextLink(links, parentContext); parentContext = null; break; - + case IGNORE: parentContext = null; break; - + case CONTINUE: default: links = addTerminatedContextAsLinks(links, specifiedParentContext); break; } } - + return buildSpan( tracer, spanId, From 094fdc4757d36ae0a475031fe9eb24ec3acd8d5a Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Wed, 19 Nov 2025 09:11:06 -0500 Subject: [PATCH 08/10] Apply suggestion from @mcculls Co-authored-by: Stuart McCulloch --- .../src/main/java/datadog/trace/core/CoreTracer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 08db9c6205f..38c5d6bbe49 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -2064,7 +2064,9 @@ protected static final DDSpanContext buildSpanContext( serviceName = tracer.serviceName; } - if (operationName == null) operationName = resourceName; + if (operationName == null) { + operationName = resourceName; + } final TagMap mergedTracerTags = traceConfig.mergedTracerTags; boolean mergedTracerTagsNeedsIntercept = traceConfig.mergedTracerTagsNeedsIntercept; From 773612e689daaa229bae07544d97c633d39f0666 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Fri, 21 Nov 2025 09:30:08 -0500 Subject: [PATCH 09/10] Addressing review feedback - Change CoreSpanBuilder constants to be more intelligible --- .../java/datadog/trace/core/CoreTracer.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 38c5d6bbe49..b462bf2f5a0 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1084,21 +1084,31 @@ static final ReusableSingleSpanBuilder reuseSingleSpanBuilder( @Override public AgentSpan startSpan(final String instrumentationName, final CharSequence spanName) { return CoreSpanBuilder.startSpan( - this, instrumentationName, spanName, null, false, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); + this, + instrumentationName, + spanName, + null, + CoreSpanBuilder.USE_SCOPE, + CoreSpanBuilder.AUTO_ASSIGN_TIMESTAMP); } @Override public AgentSpan startSpan( final String instrumentationName, final CharSequence spanName, final long startTimeMicros) { return CoreSpanBuilder.startSpan( - this, instrumentationName, spanName, null, false, startTimeMicros); + this, instrumentationName, spanName, null, CoreSpanBuilder.USE_SCOPE, startTimeMicros); } @Override public AgentSpan startSpan( String instrumentationName, final CharSequence spanName, final AgentSpanContext parent) { return CoreSpanBuilder.startSpan( - this, instrumentationName, spanName, parent, true, CoreSpanBuilder.DEFAULT_TIMESTAMP_MICRO); + this, + instrumentationName, + spanName, + parent, + CoreSpanBuilder.IGNORE_SCOPE, + CoreSpanBuilder.AUTO_ASSIGN_TIMESTAMP); } @Override @@ -1108,7 +1118,7 @@ public AgentSpan startSpan( final AgentSpanContext parent, final long startTimeMicros) { return CoreSpanBuilder.startSpan( - this, instrumentationName, spanName, parent, true, startTimeMicros); + this, instrumentationName, spanName, parent, CoreSpanBuilder.IGNORE_SCOPE, startTimeMicros); } @Override @@ -1516,9 +1526,10 @@ private static Map invertMap(Map map) { /** Spans are built using this builder */ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder { - protected static final boolean IGNORE_SCOPE_DEFAULT = false; - protected static final int SPAN_ID_DEFAULT = 0; - protected static final long DEFAULT_TIMESTAMP_MICRO = 0L; + protected static final boolean USE_SCOPE = false; + protected static final boolean IGNORE_SCOPE = true; + protected static final int AUTO_ASSIGN_SPAN_ID = 0; + protected static final long AUTO_ASSIGN_TIMESTAMP = 0L; protected final CoreTracer tracer; @@ -1534,12 +1545,12 @@ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder protected String resourceName; protected boolean errorFlag; protected CharSequence spanType; - protected boolean ignoreScope = IGNORE_SCOPE_DEFAULT; + protected boolean ignoreScope = USE_SCOPE; protected Object builderRequestContextDataAppSec; protected Object builderRequestContextDataIast; protected Object builderCiVisibilityContextData; protected List links; - protected long spanId = SPAN_ID_DEFAULT; + protected long spanId = AUTO_ASSIGN_SPAN_ID; // Make sure any fields added here are also reset properly in ReusableSingleSpanBuilder.reset CoreSpanBuilder(CoreTracer tracer) { @@ -1684,7 +1695,7 @@ protected static final AgentSpan startSpan( long timestampMicros) { return startSpan( tracer, - SPAN_ID_DEFAULT, + AUTO_ASSIGN_SPAN_ID, instrumentationName, timestampMicros, null /* serviceName */, From a41ef554bb259659b441d01fa48f1742b32ab0ea Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Fri, 21 Nov 2025 11:05:12 -0500 Subject: [PATCH 10/10] Addressing review feedback - using constants throughout --- dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index e43b508a348..71358bd7dfe 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -1935,7 +1935,7 @@ protected static final DDSpanContext buildSpanContext( final PathwayContext pathwayContext; final PropagationTags propagationTags; - if (spanId == 0) { + if (spanId == AUTO_ASSIGN_SPAN_ID) { spanId = tracer.idGenerationStrategy.generateSpanId(); }