Skip to content

Commit c67bed5

Browse files
authored
Adding Support for TRACE_PROPAGATION_BEHAVIOR_EXTRACT (#8535)
* initial implementation of TRACE_PROPAGATION_BEHAVIOR_EXTRACT * initial implementation and unit tests for TRACE_PROPAGATION_BEHAVIOR_EXTRACT * change to sampling * comments for future work * adding isremote() to all AgentSpanContexts * updating span link logic for restart * updating enum * cleanup * adding override to new class * updating enum and tests * refactoring capturing config * forcing enum to be built by build time * adding enum to skip test coverae * responding to PR comments * spotless * modifying enum constructor
1 parent 0e691f4 commit c67bed5

File tree

16 files changed

+177
-1
lines changed

16 files changed

+177
-1
lines changed

dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/trace/OtelExtractedContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,9 @@ public Iterable<Map.Entry<String, String>> baggageItems() {
7878
public PathwayContext getPathwayContext() {
7979
return null;
8080
}
81+
82+
@Override
83+
public boolean isRemote() {
84+
return true;
85+
}
8186
}

dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/NativeImageGeneratorRunnerInstrumentation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public static void onEnter(@Advice.Argument(value = 0, readOnly = false) String[
9797
+ "datadog.trace.api.ResolverCacheConfig$4:build_time,"
9898
+ "datadog.trace.api.ResolverCacheConfig$5:build_time,"
9999
+ "datadog.trace.api.TracePropagationStyle:build_time,"
100+
+ "datadog.trace.api.TracePropagationBehaviorExtract:build_time,"
100101
+ "datadog.trace.api.telemetry.OtelEnvMetricCollector:build_time,"
101102
+ "datadog.trace.api.profiling.ProfilingEnablement:build_time,"
102103
+ "datadog.trace.bootstrap.config.provider.ConfigConverter:build_time,"

dd-java-agent/instrumentation/spark/src/main/java/datadog/trace/instrumentation/spark/DatabricksParentContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,9 @@ public Iterable<Map.Entry<String, String>> baggageItems() {
9393
public PathwayContext getPathwayContext() {
9494
return null;
9595
}
96+
97+
@Override
98+
public boolean isRemote() {
99+
return false;
100+
}
96101
}

dd-java-agent/instrumentation/spark/src/main/java/datadog/trace/instrumentation/spark/OpenlineageParentContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ public PathwayContext getPathwayContext() {
143143
return null;
144144
}
145145

146+
@Override
147+
public boolean isRemote() {
148+
return false;
149+
}
150+
146151
public String getParentJobNamespace() {
147152
return parentJobNamespace;
148153
}

dd-trace-api/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ excludedClassesCoverage += [
1515
'datadog.trace.api.GlobalTracer*',
1616
'datadog.trace.api.PropagationStyle',
1717
'datadog.trace.api.TracePropagationStyle',
18+
'datadog.trace.api.TracePropagationBehaviorExtract',
1819
'datadog.trace.api.SpanCorrelation*',
1920
'datadog.trace.api.internal.TraceSegment',
2021
'datadog.trace.api.internal.TraceSegment.NoOp',

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public final class ConfigDefaults {
9191

9292
static final int DEFAULT_CLOCK_SYNC_PERIOD = 30; // seconds
9393

94+
static final TracePropagationBehaviorExtract DEFAULT_TRACE_PROPAGATION_BEHAVIOR_EXTRACT =
95+
TracePropagationBehaviorExtract.CONTINUE;
9496
static final boolean DEFAULT_TRACE_PROPAGATION_EXTRACT_FIRST = false;
9597

9698
static final boolean DEFAULT_JMX_FETCH_MULTIPLE_RUNTIME_SERVICES_ENABLED = false;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package datadog.trace.api;
2+
3+
import java.util.Locale;
4+
5+
/** Trace propagation styles for injecting and extracting trace propagation headers. */
6+
public enum TracePropagationBehaviorExtract {
7+
CONTINUE,
8+
RESTART,
9+
IGNORE;
10+
11+
private String displayName;
12+
13+
TracePropagationBehaviorExtract() {
14+
this.displayName = name().toLowerCase(Locale.ROOT);
15+
}
16+
17+
@Override
18+
public String toString() {
19+
if (displayName == null) {
20+
displayName = name().toLowerCase(Locale.ROOT);
21+
}
22+
return displayName;
23+
}
24+
}

dd-trace-api/src/main/java/datadog/trace/api/config/TracerConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public final class TracerConfig {
9393
public static final String TRACE_PROPAGATION_STYLE = "trace.propagation.style";
9494
public static final String TRACE_PROPAGATION_STYLE_EXTRACT = "trace.propagation.style.extract";
9595
public static final String TRACE_PROPAGATION_STYLE_INJECT = "trace.propagation.style.inject";
96+
public static final String TRACE_PROPAGATION_BEHAVIOR_EXTRACT =
97+
"trace.propagation.behavior.extract";
9698
public static final String TRACE_PROPAGATION_EXTRACT_FIRST = "trace.propagation.extract.first";
9799
public static final String TRACE_BAGGAGE_MAX_ITEMS = "trace.baggage.max.items";
98100
public static final String TRACE_BAGGAGE_MAX_BYTES = "trace.baggage.max.bytes";

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import datadog.trace.api.InstrumenterConfig;
3333
import datadog.trace.api.StatsDClient;
3434
import datadog.trace.api.TraceConfig;
35+
import datadog.trace.api.TracePropagationBehaviorExtract;
3536
import datadog.trace.api.config.GeneralConfig;
3637
import datadog.trace.api.datastreams.AgentDataStreamsMonitoring;
3738
import datadog.trace.api.datastreams.PathwayContext;
@@ -61,6 +62,8 @@
6162
import datadog.trace.bootstrap.instrumentation.api.BlackHoleSpan;
6263
import datadog.trace.bootstrap.instrumentation.api.ProfilingContextIntegration;
6364
import datadog.trace.bootstrap.instrumentation.api.ScopeState;
65+
import datadog.trace.bootstrap.instrumentation.api.SpanAttributes;
66+
import datadog.trace.bootstrap.instrumentation.api.SpanLink;
6467
import datadog.trace.bootstrap.instrumentation.api.TagContext;
6568
import datadog.trace.civisibility.interceptor.CiVisibilityApmProtocolInterceptor;
6669
import datadog.trace.civisibility.interceptor.CiVisibilityTelemetryInterceptor;
@@ -1506,6 +1509,28 @@ private DDSpanContext buildSpanContext() {
15061509
String parentServiceName = null;
15071510
boolean isRemote = false;
15081511

1512+
if (parentContext != null
1513+
&& parentContext.isRemote()
1514+
&& Config.get().getTracePropagationBehaviorExtract()
1515+
== TracePropagationBehaviorExtract.RESTART) {
1516+
SpanLink link;
1517+
if (parentContext instanceof ExtractedContext) {
1518+
ExtractedContext pc = (ExtractedContext) parentContext;
1519+
link =
1520+
DDSpanLink.from(
1521+
pc,
1522+
SpanAttributes.builder()
1523+
.put("reason", "propagation_behavior_extract")
1524+
.put("context_headers", pc.getPropagationStyle().toString())
1525+
.build());
1526+
} else {
1527+
link = SpanLink.from(parentContext);
1528+
}
1529+
// reset links that may have come terminated span links
1530+
links = new ArrayList<>();
1531+
links.add(link);
1532+
parentContext = null;
1533+
}
15091534
// Propagate internal trace.
15101535
// Note: if we are not in the context of distributed tracing and we are starting the first
15111536
// root span, parentContext will be null at this point.

dd-trace-core/src/test/groovy/datadog/trace/core/CoreSpanBuilderTest.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,27 @@ class CoreSpanBuilderTest extends DDCoreSpecification {
342342
new ExtractedContext(DDTraceId.from(3), 4, PrioritySampling.SAMPLER_KEEP, "some-origin", 0, ["asdf": "qwer"], [(ORIGIN_KEY): "some-origin", "zxcv": "1234"], null, PropagationTags.factory().empty(), null, DATADOG) | _
343343
}
344344

345+
def "build context from ExtractedContext with TRACE_PROPAGATION_BEHAVIOR_EXTRACT=restart"() {
346+
setup:
347+
injectSysConfig("trace.propagation.behavior.extract", "restart")
348+
def extractedContext = new ExtractedContext(DDTraceId.ONE, 2, PrioritySampling.SAMPLER_DROP, null, 0, [:], [:], null, PropagationTags.factory().fromHeaderValue(PropagationTags.HeaderType.DATADOG, "_dd.p.dm=934086a686-4,_dd.p.anytag=value"), null, DATADOG)
349+
final DDSpan span = tracer.buildSpan("test", "op name")
350+
.asChildOf(extractedContext).start()
351+
352+
expect:
353+
span.traceId != extractedContext.traceId
354+
span.parentId != extractedContext.spanId
355+
span.samplingPriority() == PrioritySampling.UNSET
356+
357+
def spanLinks = span.links
358+
359+
assert spanLinks.size() == 1
360+
def link = spanLinks[0]
361+
link.traceId() == extractedContext.traceId
362+
link.spanId() == extractedContext.spanId
363+
link.traceState() == extractedContext.propagationTags.headerValue(PropagationTags.HeaderType.W3C)
364+
}
365+
345366
def "TagContext should populate default span details"() {
346367
setup:
347368
def thread = Thread.currentThread()

0 commit comments

Comments
 (0)