Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1529,11 +1529,14 @@ void processTagsAndBaggage(
: serializedPropagationTags.createTagMap();
}

CoreTracer.ConfigSnapshot traceConfig = traceCollector.getTraceConfig();
consumer.accept(
new Metadata(
threadId,
threadName,
unsafeTags,
traceConfig.globalTags,
traceConfig.spanDefaultTags,
baggageItemsWithPropagationTags,
getSamplingPriority(),
measured,
Expand Down
23 changes: 23 additions & 0 deletions dd-trace-core/src/main/java/datadog/trace/core/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public final class Metadata {
private final UTF8BytesString threadName;
private final int httpStatusCode;
private final TagMap tags;
private final TagMap globalTags;
private final TagMap spanDefaultTags;
private final Map<String, String> baggage;

private final int samplingPriority;
Expand All @@ -30,6 +32,8 @@ public Metadata(
long threadId,
UTF8BytesString threadName,
TagMap tags,
TagMap globalTags,
TagMap spanDefaultTags,
Map<String, String> baggage,
int samplingPriority,
boolean measured,
Expand All @@ -45,6 +49,8 @@ public Metadata(
this.threadName = threadName;
this.httpStatusCode = httpStatusCode;
this.tags = tags;
this.globalTags = globalTags;
this.spanDefaultTags = spanDefaultTags;
this.baggage = baggage;
this.samplingPriority = samplingPriority;
this.measured = measured;
Expand Down Expand Up @@ -98,6 +104,23 @@ public TagMap getTags() {
return this.tags;
}

/**
* The trace's global tags ({@code DD_TAGS}, or their remote-config override). {@link #getTags()}
* already includes them, below the span defaults and the span's own tags; this lets a serializer
* that writes them once per payload, such as an OTLP resource, tell them apart.
*/
public TagMap getGlobalTags() {
return globalTags;
}

/**
* The trace's span defaults ({@code DD_SPAN_TAGS} and tracer-defined tags such as {@code env}),
* without the global tags. {@link #getTags()} already includes them, below the span's own tags.
*/
public TagMap getSpanDefaultTags() {
return spanDefaultTags;
}

public Map<String, String> getBaggage() {
return baggage;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ private static CoreSpan<?> mockSpan(CharSequence type, Map<String, Object> tags)
Thread.currentThread().getId(),
null,
TagMap.fromMap(tags),
TagMap.EMPTY,
TagMap.EMPTY,
Collections.<String, String>emptyMap(),
0,
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ void testTraceAndSpanCountsAreResetAfterAccess() {
}

DDSpan realSpan() throws Exception {
// A real config snapshot, since serialization reads the trace's tag levels from it. Its type
// isn't visible from this package, so it's held as an Object and matched by name below.
CoreTracer tracer = CoreTracer.builder().writer(new ListWriter()).build();
Object traceConfig = tracer.captureTraceConfig();
tracer.close();

// getTracer() and mapServiceName() are package-private in TraceCollector; use a custom
// Answer to handle them at runtime without compile-time accessibility issues
PendingTrace trace =
Expand All @@ -193,6 +199,9 @@ DDSpan realSpan() throws Exception {
// behavior)
return mock(CoreTracer.class);
}
if (returnType.getSimpleName().equals("ConfigSnapshot")) {
return traceConfig;
}
if (returnType == String.class) {
Object[] args = invocation.getArguments();
// mapServiceName(String) - return the argument unchanged
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ public PojoSpan(
Thread.currentThread().getId(),
UTF8BytesString.create(Thread.currentThread().getName()),
TagMap.fromMap(tags),
TagMap.EMPTY,
TagMap.EMPTY,
baggage,
samplingPriority,
measured,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -722,6 +724,39 @@ void configSnapshotSeparatesGlobalTagsFromSpanDefaults() throws Exception {
}
}

/**
* Serializers get the global tags and span defaults of the snapshot the trace started with, so a
* config change mid-trace can't split one trace across two sets.
*/
@Test
void metadataCarriesTheTraceConfigTagLevels() {
Properties properties = new Properties();
properties.setProperty(GeneralConfig.TAGS, "global_key:global_val");
properties.setProperty(TracerConfig.SPAN_TAGS, "span_key:span_val");
CoreTracer tracer = CoreTracer.builder().withProperties(properties).build();
unclosedTracers.add(tracer);

try {
ConfigSnapshot traceStartConfig = tracer.captureTraceConfig();
DDSpan span = (DDSpan) tracer.buildSpan("datadog", "my_span").start();

Properties changed = new Properties();
changed.setProperty(GeneralConfig.TAGS, "other_key:other_val");
tracer.rebuildTraceConfig(Config.get(changed));
assertNotSame(traceStartConfig.globalTags, tracer.captureTraceConfig().globalTags);

Metadata[] captured = {null};
span.processTagsAndBaggage(metadata -> captured[0] = metadata, 0);

assertSame(traceStartConfig.globalTags, captured[0].getGlobalTags());
assertSame(traceStartConfig.spanDefaultTags, captured[0].getSpanDefaultTags());
assertEquals(buildStringMap("global_key", "global_val"), captured[0].getGlobalTags());
assertEquals(buildStringMap("span_key", "span_val"), captured[0].getSpanDefaultTags());
} finally {
tracer.close();
}
}

static final String ACTION_JSON =
"'{\"action\": \"enable\", \"lib_config\":"
+ "{\"tracing_sampling_rate\": null,"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ private static Metadata metadataWithStatus(int status) {
Thread.currentThread().getId(),
UTF8BytesString.create("main"),
TagMap.fromMap(emptyMap()),
TagMap.EMPTY,
TagMap.EMPTY,
emptyMap(),
0,
false,
Expand Down
2 changes: 2 additions & 0 deletions dd-trace-core/src/traceAgentTest/java/TraceGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ static class PojoSpan implements CoreSpan<PojoSpan> {
currentThread().getId(),
UTF8BytesString.create(currentThread().getName()),
fromMap(tags),
TagMap.EMPTY,
TagMap.EMPTY,
baggage,
UNSET,
measured,
Expand Down
Loading