Remove codec for inject/extract

In preparation for OT 0.32 support.
This commit is contained in:
Tyler Benson 2019-02-05 14:49:07 -08:00
parent 7a430647a0
commit 326577d7df
7 changed files with 330 additions and 378 deletions

View File

@ -2,9 +2,8 @@ package datadog.opentracing;
import datadog.opentracing.decorators.AbstractDecorator;
import datadog.opentracing.decorators.DDDecoratorsFactory;
import datadog.opentracing.propagation.Codec;
import datadog.opentracing.propagation.DatadogHttpCodec;
import datadog.opentracing.propagation.ExtractedContext;
import datadog.opentracing.propagation.HTTPCodec;
import datadog.opentracing.propagation.TagContext;
import datadog.opentracing.scopemanager.ContextualScopeManager;
import datadog.opentracing.scopemanager.ScopeContext;
@ -24,6 +23,7 @@ import io.opentracing.ScopeManager;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
@ -84,7 +84,9 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
return Integer.compare(o1.priority(), o2.priority());
}
});
private final CodecRegistry registry;
private final DatadogHttpCodec.Injector injector;
private final DatadogHttpCodec.Extractor extractor;
private final AtomicInteger traceCount;
@ -238,9 +240,9 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
// The JVM is already shutting down.
}
registry = new CodecRegistry();
registry.register(Format.Builtin.HTTP_HEADERS, new HTTPCodec(taggedHeaders));
registry.register(Format.Builtin.TEXT_MAP, new HTTPCodec(taggedHeaders));
injector = new DatadogHttpCodec.Injector();
extractor = new DatadogHttpCodec.Extractor(taggedHeaders);
if (this.writer instanceof DDAgentWriter) {
final DDApi api = ((DDAgentWriter) this.writer).getApi();
traceCount = api.getTraceCounter();
@ -332,24 +334,21 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
@Override
public <T> void inject(final SpanContext spanContext, final Format<T> format, final T carrier) {
final Codec<T> codec = registry.get(format);
if (codec == null) {
if (!(carrier instanceof TextMap)) {
log.debug("Unsupported format for propagation - {}", format.getClass().getName());
} else {
codec.inject((DDSpanContext) spanContext, carrier);
injector.inject((DDSpanContext) spanContext, (TextMap) carrier);
}
}
@Override
public <T> SpanContext extract(final Format<T> format, final T carrier) {
final Codec<T> codec = registry.get(format);
if (codec == null) {
if (!(carrier instanceof TextMap)) {
log.debug("Unsupported format for propagation - {}", format.getClass().getName());
return null;
} else {
return codec.extract(carrier);
return extractor.extract((TextMap) carrier);
}
return null;
}
/**
@ -452,19 +451,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
return Config.get().getPartialFlushMinSpans();
}
private static class CodecRegistry {
private final Map<Format<?>, Codec<?>> codecs = new HashMap<>();
<T> Codec<T> get(final Format<T> format) {
return (Codec<T>) codecs.get(format);
}
public <T> void register(final Format<T> format, final Codec<T> codec) {
codecs.put(format, codec);
}
}
/** Spans are built using this builder */
public class DDSpanBuilder implements SpanBuilder {
private final ScopeManager scopeManager;

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2016, Uber Technologies, Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package datadog.opentracing.propagation;
import datadog.opentracing.DDSpanContext;
import io.opentracing.SpanContext;
/** A codec is a simple object that can encode and decode a span context through a carrier */
public interface Codec<T> {
/**
* Serialize the span context using the provided carrier
*
* @param context
* @param carrier
*/
void inject(DDSpanContext context, T carrier);
/**
* Given a carrier, retrieve (rebuild) a span context. This context built will be use as the
* parent
*
* @param carrier
* @return the span context
*/
SpanContext extract(T carrier);
}

View File

@ -0,0 +1,150 @@
package datadog.opentracing.propagation;
import datadog.opentracing.DDSpanContext;
import datadog.trace.api.sampling.PrioritySampling;
import io.opentracing.SpanContext;
import io.opentracing.propagation.TextMap;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
/** A codec designed for HTTP transport via headers */
@Slf4j
public class DatadogHttpCodec {
// uint 64 bits max value, 2^64 - 1
static final BigInteger BIG_INTEGER_UINT64_MAX =
new BigInteger("2").pow(64).subtract(BigInteger.ONE);
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-";
private static final String TRACE_ID_KEY = "x-datadog-trace-id";
private static final String SPAN_ID_KEY = "x-datadog-parent-id";
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority";
public static class Injector {
public void inject(final DDSpanContext context, final TextMap carrier) {
carrier.put(TRACE_ID_KEY, String.valueOf(context.getTraceId()));
carrier.put(SPAN_ID_KEY, String.valueOf(context.getSpanId()));
if (context.lockSamplingPriority()) {
carrier.put(SAMPLING_PRIORITY_KEY, String.valueOf(context.getSamplingPriority()));
}
for (final Map.Entry<String, String> entry : context.baggageItems()) {
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), encode(entry.getValue()));
}
log.debug("{} - Parent context injected", context.getTraceId());
}
private String encode(final String value) {
String encoded = value;
try {
encoded = URLEncoder.encode(value, "UTF-8");
} catch (final UnsupportedEncodingException e) {
log.info("Failed to encode value - {}", value);
}
return encoded;
}
}
public static class Extractor {
private final Map<String, String> taggedHeaders;
public Extractor(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());
}
}
public SpanContext extract(final TextMap carrier) {
Map<String, String> baggage = Collections.emptyMap();
Map<String, String> tags = Collections.emptyMap();
String traceId = "0";
String spanId = "0";
int samplingPriority = PrioritySampling.UNSET;
for (final Map.Entry<String, String> entry : carrier) {
final String key = entry.getKey().toLowerCase();
final String val = entry.getValue();
if (val == null) {
continue;
}
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
traceId = validateUInt64BitsID(val);
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
spanId = validateUInt64BitsID(val);
} else if (key.startsWith(OT_BAGGAGE_PREFIX)) {
if (baggage.isEmpty()) {
baggage = new HashMap<>();
}
baggage.put(key.replace(OT_BAGGAGE_PREFIX, ""), decode(val));
} else if (SAMPLING_PRIORITY_KEY.equalsIgnoreCase(key)) {
samplingPriority = Integer.parseInt(val);
}
if (taggedHeaders.containsKey(key)) {
if (tags.isEmpty()) {
tags = new HashMap<>();
}
tags.put(taggedHeaders.get(key), decode(val));
}
}
SpanContext context = null;
if (!"0".equals(traceId)) {
final ExtractedContext ctx =
new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags);
ctx.lockSamplingPriority();
log.debug("{} - Parent context extracted", ctx.getTraceId());
context = ctx;
} else if (!tags.isEmpty()) {
context = new TagContext(tags);
}
return context;
}
private String decode(final String value) {
String decoded = value;
try {
decoded = URLDecoder.decode(value, "UTF-8");
} catch (final UnsupportedEncodingException e) {
log.info("Failed to decode value - {}", value);
}
return decoded;
}
/**
* Helper method to validate an ID String to verify that it is an unsigned 64 bits number and is
* within range.
*
* @param val the String that contains the ID
* @return the ID in String format if it passes validations
* @throws IllegalArgumentException if val is not a number or if the number is out of range
*/
private String validateUInt64BitsID(final String val) throws IllegalArgumentException {
try {
final BigInteger validate = new BigInteger(val);
if (validate.compareTo(BigInteger.ZERO) == -1
|| validate.compareTo(BIG_INTEGER_UINT64_MAX) == 1) {
throw new IllegalArgumentException(
"ID out of range, must be between 0 and 2^64-1, got: " + val);
}
return val;
} catch (final NumberFormatException nfe) {
throw new IllegalArgumentException(
"Expecting a number for trace ID or span ID, but got: " + val, nfe);
}
}
}
}

View File

@ -1,147 +0,0 @@
package datadog.opentracing.propagation;
import datadog.opentracing.DDSpanContext;
import datadog.trace.api.sampling.PrioritySampling;
import io.opentracing.SpanContext;
import io.opentracing.propagation.TextMap;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
/** A codec designed for HTTP transport via headers */
@Slf4j
public class HTTPCodec implements Codec<TextMap> {
// uint 64 bits max value, 2^64 - 1
static final BigInteger BIG_INTEGER_UINT64_MAX =
new BigInteger("2").pow(64).subtract(BigInteger.ONE);
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-";
private static final String TRACE_ID_KEY = "x-datadog-trace-id";
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()));
carrier.put(SPAN_ID_KEY, String.valueOf(context.getSpanId()));
if (context.lockSamplingPriority()) {
carrier.put(SAMPLING_PRIORITY_KEY, String.valueOf(context.getSamplingPriority()));
}
for (final Map.Entry<String, String> entry : context.baggageItems()) {
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), encode(entry.getValue()));
}
log.debug("{} - Parent context injected", context.getTraceId());
}
@Override
public SpanContext extract(final TextMap carrier) {
Map<String, String> baggage = Collections.emptyMap();
Map<String, String> tags = Collections.emptyMap();
String traceId = "0";
String spanId = "0";
int samplingPriority = PrioritySampling.UNSET;
for (final Map.Entry<String, String> entry : carrier) {
final String key = entry.getKey().toLowerCase();
final String val = entry.getValue();
if (val == null) {
continue;
}
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
traceId = validateUInt64BitsID(val);
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
spanId = validateUInt64BitsID(val);
} else if (key.startsWith(OT_BAGGAGE_PREFIX)) {
if (baggage.isEmpty()) {
baggage = new HashMap<>();
}
baggage.put(key.replace(OT_BAGGAGE_PREFIX, ""), decode(val));
} else if (SAMPLING_PRIORITY_KEY.equalsIgnoreCase(key)) {
samplingPriority = Integer.parseInt(val);
}
if (taggedHeaders.containsKey(key)) {
if (tags.isEmpty()) {
tags = new HashMap<>();
}
tags.put(taggedHeaders.get(key), decode(val));
}
}
SpanContext context = null;
if (!"0".equals(traceId)) {
final ExtractedContext ctx =
new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags);
ctx.lockSamplingPriority();
log.debug("{} - Parent context extracted", ctx.getTraceId());
context = ctx;
} else if (!tags.isEmpty()) {
context = new TagContext(tags);
}
return context;
}
private String encode(final String value) {
String encoded = value;
try {
encoded = URLEncoder.encode(value, "UTF-8");
} catch (final UnsupportedEncodingException e) {
log.info("Failed to encode value - {}", value);
}
return encoded;
}
private String decode(final String value) {
String decoded = value;
try {
decoded = URLDecoder.decode(value, "UTF-8");
} catch (final UnsupportedEncodingException e) {
log.info("Failed to decode value - {}", value);
}
return decoded;
}
/**
* Helper method to validate an ID String to verify that it is an unsigned 64 bits number and is
* within range.
*
* @param val the String that contains the ID
* @return the ID in String format if it passes validations
* @throws IllegalArgumentException if val is not a number or if the number is out of range
*/
private String validateUInt64BitsID(final String val) throws IllegalArgumentException {
try {
final BigInteger validate = new BigInteger(val);
if (validate.compareTo(BigInteger.ZERO) == -1
|| validate.compareTo(BIG_INTEGER_UINT64_MAX) == 1) {
throw new IllegalArgumentException(
"ID out of range, must be between 0 and 2^64-1, got: " + val);
}
return val;
} catch (final NumberFormatException nfe) {
throw new IllegalArgumentException(
"Expecting a number for trace ID or span ID, but got: " + val, nfe);
}
}
}

View File

@ -1,160 +1,18 @@
package datadog.opentracing.propagation
import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter
import io.opentracing.propagation.TextMapExtractAdapter
import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Shared
import spock.lang.Specification
import static datadog.opentracing.propagation.HTTPCodec.BIG_INTEGER_UINT64_MAX
import static datadog.opentracing.propagation.DatadogHttpCodec.BIG_INTEGER_UINT64_MAX
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
import static datadog.opentracing.propagation.DatadogHttpCodec.SAMPLING_PRIORITY_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
class HTTPCodecTest extends Specification {
@Shared
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-"
@Shared
private static final String TRACE_ID_KEY = "x-datadog-trace-id"
@Shared
private static final String SPAN_ID_KEY = "x-datadog-parent-id"
@Shared
private static final String SAMPLING_PRIORITY_KEY = "x-datadog-sampling-priority"
class DatadogHttpExtractorTest extends Specification {
HTTPCodec codec = new HTTPCodec(["SOME_HEADER": "some-tag"])
def "inject http headers"() {
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
"1",
"2",
"0",
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, "1", [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == "1"
carrier.get(SPAN_ID_KEY) == "2"
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
def "inject http headers with larger than Java long IDs"() {
String largeTraceId = "9523372036854775807"
String largeSpanId = "15815582334751494918"
String largeParentId = "15815582334751494914"
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
largeTraceId,
largeSpanId,
largeParentId,
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, largeTraceId, [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == largeTraceId
carrier.get(SPAN_ID_KEY) == largeSpanId
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
def "inject http headers with uint 64 max IDs"() {
String largeTraceId = "18446744073709551615"
String largeSpanId = "18446744073709551614"
String largeParentId = "18446744073709551613"
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
largeTraceId,
largeSpanId,
largeParentId,
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, largeTraceId, [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
codec.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == largeTraceId
carrier.get(SPAN_ID_KEY) == largeSpanId
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
DatadogHttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"])
def "extract http headers"() {
setup:
@ -170,7 +28,7 @@ class HTTPCodecTest extends Specification {
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
}
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
expect:
context.getTraceId() == "1"
@ -192,7 +50,7 @@ class HTTPCodecTest extends Specification {
SOME_HEADER: "my-interesting-info",
]
TagContext context = codec.extract(new TextMapExtractAdapter(actual))
TagContext context = extractor.extract(new TextMapExtractAdapter(actual))
expect:
!(context instanceof ExtractedContext)
@ -201,7 +59,7 @@ class HTTPCodecTest extends Specification {
def "extract empty headers returns null"() {
expect:
codec.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
extractor.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
}
def "extract http headers with larger than Java long IDs"() {
@ -220,7 +78,7 @@ class HTTPCodecTest extends Specification {
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
}
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
expect:
context.getTraceId() == largeTraceId
@ -251,7 +109,7 @@ class HTTPCodecTest extends Specification {
actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority))
}
final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual))
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(actual))
expect:
context.getTraceId() == BIG_INTEGER_UINT64_MAX.toString()
@ -282,7 +140,7 @@ class HTTPCodecTest extends Specification {
}
when:
codec.extract(new TextMapExtractAdapter(actual))
extractor.extract(new TextMapExtractAdapter(actual))
then:
def iae = thrown(IllegalArgumentException)
@ -310,7 +168,7 @@ class HTTPCodecTest extends Specification {
}
when:
codec.extract(new TextMapExtractAdapter(actual))
extractor.extract(new TextMapExtractAdapter(actual))
then:
thrown(IllegalArgumentException)
@ -336,7 +194,7 @@ class HTTPCodecTest extends Specification {
}
when:
codec.extract(new TextMapExtractAdapter(actual))
extractor.extract(new TextMapExtractAdapter(actual))
then:
thrown(IllegalArgumentException)

View File

@ -0,0 +1,151 @@
package datadog.opentracing.propagation
import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter
import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
import static datadog.opentracing.propagation.DatadogHttpCodec.SAMPLING_PRIORITY_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
class DatadogHttpInjectorTest extends Specification {
DatadogHttpCodec.Injector injector = new DatadogHttpCodec.Injector()
def "inject http headers"() {
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
"1",
"2",
"0",
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, "1", [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == "1"
carrier.get(SPAN_ID_KEY) == "2"
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
def "inject http headers with larger than Java long IDs"() {
String largeTraceId = "9523372036854775807"
String largeSpanId = "15815582334751494918"
String largeParentId = "15815582334751494914"
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
largeTraceId,
largeSpanId,
largeParentId,
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, largeTraceId, [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == largeTraceId
carrier.get(SPAN_ID_KEY) == largeSpanId
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
def "inject http headers with uint 64 max IDs"() {
String largeTraceId = "18446744073709551615"
String largeSpanId = "18446744073709551614"
String largeParentId = "18446744073709551613"
setup:
def writer = new ListWriter()
def tracer = new DDTracer(writer)
final DDSpanContext mockedContext =
new DDSpanContext(
largeTraceId,
largeSpanId,
largeParentId,
"fakeService",
"fakeOperation",
"fakeResource",
samplingPriority,
new HashMap<String, String>() {
{
put("k1", "v1")
put("k2", "v2")
}
},
false,
"fakeType",
null,
new PendingTrace(tracer, largeTraceId, [:]),
tracer)
final Map<String, String> carrier = new HashMap<>()
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
expect:
carrier.get(TRACE_ID_KEY) == largeTraceId
carrier.get(SPAN_ID_KEY) == largeSpanId
carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority))
carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1"
carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2"
where:
samplingPriority | _
PrioritySampling.UNSET | _
PrioritySampling.SAMPLER_KEEP | _
}
}

View File

@ -78,7 +78,7 @@ class DDTracerTest extends Specification {
when:
def config = new Config()
def tracer = new DDTracer(config)
def taggedHeaders = tracer.registry.codecs.values().first().taggedHeaders
def taggedHeaders = tracer.extractor.taggedHeaders
then:
tracer.defaultSpanTags == map