Skip to content
Merged
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
20 changes: 15 additions & 5 deletions dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public DDTracer(final Properties config) {
Writer.Builder.forConfig(config),
Sampler.Builder.forConfig(config),
DDTraceConfig.parseMap(config.getProperty(DDTraceConfig.SPAN_TAGS)),
DDTraceConfig.parseMap(config.getProperty(DDTraceConfig.SERVICE_MAPPING)));
DDTraceConfig.parseMap(config.getProperty(DDTraceConfig.SERVICE_MAPPING)),
DDTraceConfig.parseMap(config.getProperty(DDTraceConfig.HEADER_TAGS)));
log.debug("Using config: {}", config);
}

Expand All @@ -99,6 +100,7 @@ public DDTracer(final String serviceName, final Writer writer, final Sampler sam
writer,
sampler,
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap());
}

Expand All @@ -107,16 +109,17 @@ public DDTracer(
final Writer writer,
final Sampler sampler,
final Map<String, String> defaultSpanTags,
final Map<String, String> serviceNameMappings) {
final Map<String, String> serviceNameMappings,
final Map<String, String> taggedHeaders) {
this.serviceName = serviceName;
this.writer = writer;
this.writer.start();
this.sampler = sampler;
this.spanTags = defaultSpanTags;

registry = new CodecRegistry();
registry.register(Format.Builtin.HTTP_HEADERS, new HTTPCodec());
registry.register(Format.Builtin.TEXT_MAP, new HTTPCodec());
registry.register(Format.Builtin.HTTP_HEADERS, new HTTPCodec(taggedHeaders));
registry.register(Format.Builtin.TEXT_MAP, new HTTPCodec(taggedHeaders));
if (this.writer instanceof DDAgentWriter && sampler instanceof DDApi.ResponseListener) {
final DDApi api = ((DDAgentWriter) this.writer).getApi();
api.addResponseListener((DDApi.ResponseListener) this.sampler);
Expand All @@ -141,7 +144,8 @@ public DDTracer(final Writer writer) {
writer,
new AllSampler(),
DDTraceConfig.parseMap(new DDTraceConfig().getProperty(DDTraceConfig.SPAN_TAGS)),
DDTraceConfig.parseMap(new DDTraceConfig().getProperty(DDTraceConfig.SERVICE_MAPPING)));
DDTraceConfig.parseMap(new DDTraceConfig().getProperty(DDTraceConfig.SERVICE_MAPPING)),
DDTraceConfig.parseMap(new DDTraceConfig().getProperty(DDTraceConfig.HEADER_TAGS)));
}

/**
Expand Down Expand Up @@ -488,6 +492,12 @@ private DDSpanContext buildSpanContext() {
traceId = ddsc.getTraceId();
parentSpanId = ddsc.getSpanId();
baggage = ddsc.getBaggage();
if (this.tags.isEmpty() && !ddsc.getTags().isEmpty()) {
this.tags = new HashMap<>();
}
if (!ddsc.getTags().isEmpty()) {
tags.putAll(ddsc.getTags());
}
parentTrace = new PendingTrace(DDTracer.this, traceId);
samplingPriority = ddsc.getSamplingPriority();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ public class ExtractedContext implements SpanContext {
private final Long spanId;
private final int samplingPriority;
private final Map<String, String> baggage;
private final Map<String, String> tags;
private final AtomicBoolean samplingPriorityLocked = new AtomicBoolean(false);

public ExtractedContext(
final Long traceId,
final Long spanId,
final int samplingPriority,
final Map<String, String> baggage) {
final Map<String, String> baggage,
final Map<String, String> tags) {
this.traceId = traceId;
this.spanId = spanId;
this.samplingPriority = samplingPriority;
this.baggage = baggage;
this.tags = tags;
}

@Override
Expand Down Expand Up @@ -47,6 +50,10 @@ public Map<String, String> getBaggage() {
return baggage;
}

public Map<String, String> getTags() {
return tags;
}

public boolean getSamplingPriorityLocked() {
return samplingPriorityLocked.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ public class HTTPCodec implements Codec<TextMap> {
private static final String SPAN_ID_KEY = "x-datadog-parent-id";
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority";

private final Map<String, String> taggedHeaders;

public HTTPCodec(final Map<String, String> taggedHeaders) {
this.taggedHeaders = new HashMap<>();
for (final Map.Entry<String, String> mapping : taggedHeaders.entrySet()) {
this.taggedHeaders.put(mapping.getKey().trim().toLowerCase(), mapping.getValue());
}
}

@Override
public void inject(final DDSpanContext context, final TextMap carrier) {
carrier.put(TRACE_ID_KEY, String.valueOf(context.getTraceId()));
Expand All @@ -38,6 +47,7 @@ public void inject(final DDSpanContext context, final TextMap carrier) {
public ExtractedContext extract(final TextMap carrier) {

Map<String, String> baggage = Collections.emptyMap();
Map<String, String> tags = Collections.emptyMap();
Long traceId = 0L;
Long spanId = 0L;
int samplingPriority = PrioritySampling.UNSET;
Expand All @@ -56,10 +66,17 @@ public ExtractedContext extract(final TextMap carrier) {
} else if (key.equalsIgnoreCase(SAMPLING_PRIORITY_KEY)) {
samplingPriority = Integer.parseInt(entry.getValue());
}

if (taggedHeaders.containsKey(key)) {
if (tags.isEmpty()) {
tags = new HashMap<>();
}
tags.put(taggedHeaders.get(key), decode(entry.getValue()));
}
}
ExtractedContext context = null;
if (traceId != 0L) {
context = new ExtractedContext(traceId, spanId, samplingPriority, baggage);
context = new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags);
context.lockSamplingPriority();

log.debug("{} - Parent context extracted", context.getTraceId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class DDTraceConfig extends Properties {
public static final String AGENT_PORT = "agent.port";
public static final String PRIORITY_SAMPLING = "priority.sampling";
public static final String SPAN_TAGS = "trace.span.tags";
public static final String HEADER_TAGS = "trace.header.tags";
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@realark Do you have any better ideas for names for these settings?


private final String serviceName = getPropOrEnv(PREFIX + SERVICE_NAME);
private final String serviceMapping = getPropOrEnv(PREFIX + SERVICE_MAPPING);
Expand All @@ -38,6 +39,7 @@ public class DDTraceConfig extends Properties {
private final String agentPort = getPropOrEnv(PREFIX + AGENT_PORT);
private final String prioritySampling = getPropOrEnv(PREFIX + PRIORITY_SAMPLING);
private final String spanTags = getPropOrEnv(PREFIX + SPAN_TAGS);
private final String headerTags = getPropOrEnv(PREFIX + HEADER_TAGS);

public DDTraceConfig() {
super();
Expand All @@ -56,6 +58,7 @@ public DDTraceConfig() {
setIfNotNull(AGENT_PORT, agentPort);
setIfNotNull(PRIORITY_SAMPLING, prioritySampling);
setIfNotNull(SPAN_TAGS, spanTags);
setIfNotNull(HEADER_TAGS, headerTags);
}

public DDTraceConfig(final String serviceName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.opentracing

import datadog.opentracing.propagation.ExtractedContext
import datadog.trace.api.DDTags
import datadog.trace.common.writer.ListWriter
import spock.lang.Specification
Expand Down Expand Up @@ -222,6 +223,24 @@ class DDSpanBuilderTest extends Specification {
spans[(int) (Math.random() * nbSamples)].context.trace.containsAll(spans)
}

def "ExtractedContext should populate new span details"() {
setup:
final DDSpan span = tracer.buildSpan("op name")
.asChildOf(extractedContext).start()

expect:
span.traceId == extractedContext.traceId
span.parentId == extractedContext.spanId
span.samplingPriority == extractedContext.samplingPriority
span.context().baggageItems == extractedContext.baggage
span.context().@tags == extractedContext.tags

where:
extractedContext | _
new ExtractedContext(1, 2, 0, [:], [:]) | _
new ExtractedContext(3, 4, 1, ["asdf": "qwer"], ["zxcv": "1234"]) | _
}

def "global span tags populated on each span"() {
setup:
System.setProperty("dd.trace.span.tags", tagString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class HTTPCodecTest extends Specification {
@Shared
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority"

HTTPCodec codec = new HTTPCodec(["SOME_HEADER": "some-tag"])

def "inject http headers"() {
setup:
def writer = new ListWriter()
Expand Down Expand Up @@ -47,7 +49,6 @@ class HTTPCodecTest extends Specification {

final Map<String, String> carrier = new HashMap<>()

final HTTPCodec codec = new HTTPCodec()
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))

expect:
Expand All @@ -70,20 +71,21 @@ class HTTPCodecTest extends Specification {
(SPAN_ID_KEY.toUpperCase()) : "2",
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
SOME_HEADER : "my-interesting-info",
]

if (samplingPriority != PrioritySampling.UNSET) {
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
}

final HTTPCodec codec = new HTTPCodec()
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))

expect:
context.getTraceId() == 1l
context.getSpanId() == 2l
context.getBaggage().get("k1") == "v1"
context.getBaggage().get("k2") == "v2"
context.getTags() == ["some-tag": "my-interesting-info"]
context.getSamplingPriority() == samplingPriority

where:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import spock.lang.Specification

import static datadog.trace.common.DDTraceConfig.AGENT_HOST
import static datadog.trace.common.DDTraceConfig.AGENT_PORT
import static datadog.trace.common.DDTraceConfig.HEADER_TAGS
import static datadog.trace.common.DDTraceConfig.PREFIX
import static datadog.trace.common.DDTraceConfig.SERVICE_MAPPING
import static datadog.trace.common.DDTraceConfig.SERVICE_NAME
Expand Down Expand Up @@ -114,16 +115,19 @@ class DDTraceConfigTest extends Specification {
setup:
System.setProperty(PREFIX + SERVICE_MAPPING, mapString)
System.setProperty(PREFIX + SPAN_TAGS, mapString)
System.setProperty(PREFIX + HEADER_TAGS, mapString)

when:
def tracer = new DDTracer()
ServiceNameDecorator decorator = tracer.spanContextDecorators.values().flatten().find {
it instanceof ServiceNameDecorator
}
def taggedHeaders = tracer.registry.codecs.values().first().taggedHeaders

then:
tracer.spanTags == map
decorator.mappings == map
taggedHeaders == map

where:
mapString | map
Expand Down