Remove propagation formats (#24)
* Remove Haystack propagation format * Remove B3 propagation format * Remove header tags * Remove origin * Remove TagContext class * Remove baggage items * Remove propagation config
This commit is contained in:
parent
9f322c0a59
commit
e6ad427130
|
|
@ -9,7 +9,8 @@ excludedClassesCoverage += [
|
|||
'datadog.trace.api.DDTraceApiInfo',
|
||||
'datadog.trace.api.GlobalTracer*',
|
||||
'datadog.trace.api.CorrelationIdentifier',
|
||||
'datadog.trace.api.DDTags'
|
||||
'datadog.trace.api.DDTags',
|
||||
'datadog.trace.api.Config'
|
||||
]
|
||||
|
||||
description = 'dd-trace-api'
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ public class Config {
|
|||
public static final String TRACE_METHODS = "trace.methods";
|
||||
public static final String TRACE_CLASSES_EXCLUDE = "trace.classes.exclude";
|
||||
public static final String TRACE_REPORT_HOSTNAME = "trace.report-hostname";
|
||||
public static final String HEADER_TAGS = "trace.header.tags";
|
||||
public static final String HTTP_SERVER_ERROR_STATUSES = "http.server.error.statuses";
|
||||
public static final String HTTP_CLIENT_ERROR_STATUSES = "http.client.error.statuses";
|
||||
public static final String HTTP_SERVER_TAG_QUERY_STRING = "http.server.tag.query-string";
|
||||
|
|
@ -70,8 +69,6 @@ public class Config {
|
|||
public static final String PARTIAL_FLUSH_MIN_SPANS = "trace.partial.flush.min.spans";
|
||||
public static final String RUNTIME_CONTEXT_FIELD_INJECTION =
|
||||
"trace.runtime.context.field.injection";
|
||||
public static final String PROPAGATION_STYLE_EXTRACT = "propagation.style.extract";
|
||||
public static final String PROPAGATION_STYLE_INJECT = "propagation.style.inject";
|
||||
|
||||
public static final String HEALTH_METRICS_ENABLED = "trace.health.metrics.enabled";
|
||||
public static final String HEALTH_METRICS_STATSD_HOST = "trace.health.metrics.statsd.host";
|
||||
|
|
@ -109,8 +106,6 @@ public class Config {
|
|||
private static final boolean DEFAULT_HTTP_CLIENT_SPLIT_BY_DOMAIN = false;
|
||||
private static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE = false;
|
||||
private static final int DEFAULT_PARTIAL_FLUSH_MIN_SPANS = 1000;
|
||||
private static final String DEFAULT_PROPAGATION_STYLE_EXTRACT = PropagationStyle.DATADOG.name();
|
||||
private static final String DEFAULT_PROPAGATION_STYLE_INJECT = PropagationStyle.DATADOG.name();
|
||||
|
||||
public static final boolean DEFAULT_METRICS_ENABLED = false;
|
||||
// No default constants for metrics statsd support -- falls back to jmx fetch values
|
||||
|
|
@ -125,12 +120,6 @@ public class Config {
|
|||
private static final String DEFAULT_TRACE_EXECUTORS = "";
|
||||
private static final String DEFAULT_TRACE_METHODS = null;
|
||||
|
||||
public enum PropagationStyle {
|
||||
DATADOG,
|
||||
B3,
|
||||
HAYSTACK
|
||||
}
|
||||
|
||||
/** A tag intended for internal use only, hence not added to the public api DDTags class. */
|
||||
private static final String INTERNAL_HOST_NAME = "_dd.hostname";
|
||||
|
||||
|
|
@ -152,7 +141,6 @@ public class Config {
|
|||
private final Map<String, String> spanTags;
|
||||
private final Map<String, String> jmxTags;
|
||||
@Getter private final List<String> excludedClasses;
|
||||
@Getter private final Map<String, String> headerTags;
|
||||
@Getter private final Set<Integer> httpServerErrorStatuses;
|
||||
@Getter private final Set<Integer> httpClientErrorStatuses;
|
||||
@Getter private final boolean httpServerTagQueryString;
|
||||
|
|
@ -161,8 +149,6 @@ public class Config {
|
|||
@Getter private final boolean dbClientSplitByInstance;
|
||||
@Getter private final Integer partialFlushMinSpans;
|
||||
@Getter private final boolean runtimeContextFieldInjection;
|
||||
@Getter private final Set<PropagationStyle> propagationStylesToExtract;
|
||||
@Getter private final Set<PropagationStyle> propagationStylesToInject;
|
||||
|
||||
@Getter private final boolean healthMetricsEnabled;
|
||||
@Getter private final String healthMetricsStatsdHost;
|
||||
|
|
@ -210,7 +196,6 @@ public class Config {
|
|||
jmxTags = getMapSettingFromEnvironment(JMX_TAGS, null);
|
||||
|
||||
excludedClasses = getListSettingFromEnvironment(TRACE_CLASSES_EXCLUDE, null);
|
||||
headerTags = getMapSettingFromEnvironment(HEADER_TAGS, null);
|
||||
|
||||
httpServerErrorStatuses =
|
||||
getIntegerRangeSettingFromEnvironment(
|
||||
|
|
@ -243,19 +228,6 @@ public class Config {
|
|||
getBooleanSettingFromEnvironment(
|
||||
RUNTIME_CONTEXT_FIELD_INJECTION, DEFAULT_RUNTIME_CONTEXT_FIELD_INJECTION);
|
||||
|
||||
propagationStylesToExtract =
|
||||
getEnumSetSettingFromEnvironment(
|
||||
PROPAGATION_STYLE_EXTRACT,
|
||||
DEFAULT_PROPAGATION_STYLE_EXTRACT,
|
||||
PropagationStyle.class,
|
||||
true);
|
||||
propagationStylesToInject =
|
||||
getEnumSetSettingFromEnvironment(
|
||||
PROPAGATION_STYLE_INJECT,
|
||||
DEFAULT_PROPAGATION_STYLE_INJECT,
|
||||
PropagationStyle.class,
|
||||
true);
|
||||
|
||||
// Writer.Builder createMonitor will use the values of the JMX fetch & agent to fill-in defaults
|
||||
healthMetricsEnabled =
|
||||
getBooleanSettingFromEnvironment(HEALTH_METRICS_ENABLED, DEFAULT_METRICS_ENABLED);
|
||||
|
|
@ -306,7 +278,6 @@ public class Config {
|
|||
jmxTags = getPropertyMapValue(properties, JMX_TAGS, parent.jmxTags);
|
||||
excludedClasses =
|
||||
getPropertyListValue(properties, TRACE_CLASSES_EXCLUDE, parent.excludedClasses);
|
||||
headerTags = getPropertyMapValue(properties, HEADER_TAGS, parent.headerTags);
|
||||
|
||||
httpServerErrorStatuses =
|
||||
getPropertyIntegerRangeValue(
|
||||
|
|
@ -339,19 +310,6 @@ public class Config {
|
|||
getPropertyBooleanValue(
|
||||
properties, RUNTIME_CONTEXT_FIELD_INJECTION, parent.runtimeContextFieldInjection);
|
||||
|
||||
final Set<PropagationStyle> parsedPropagationStylesToExtract =
|
||||
getPropertySetValue(properties, PROPAGATION_STYLE_EXTRACT, PropagationStyle.class);
|
||||
propagationStylesToExtract =
|
||||
parsedPropagationStylesToExtract == null
|
||||
? parent.propagationStylesToExtract
|
||||
: parsedPropagationStylesToExtract;
|
||||
final Set<PropagationStyle> parsedPropagationStylesToInject =
|
||||
getPropertySetValue(properties, PROPAGATION_STYLE_INJECT, PropagationStyle.class);
|
||||
propagationStylesToInject =
|
||||
parsedPropagationStylesToInject == null
|
||||
? parent.propagationStylesToInject
|
||||
: parsedPropagationStylesToInject;
|
||||
|
||||
healthMetricsEnabled =
|
||||
getPropertyBooleanValue(properties, HEALTH_METRICS_ENABLED, DEFAULT_METRICS_ENABLED);
|
||||
healthMetricsStatsdHost =
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import static datadog.trace.api.Config.AGENT_UNIX_DOMAIN_SOCKET
|
|||
import static datadog.trace.api.Config.CONFIGURATION_FILE
|
||||
import static datadog.trace.api.Config.DB_CLIENT_HOST_SPLIT_BY_INSTANCE
|
||||
import static datadog.trace.api.Config.GLOBAL_TAGS
|
||||
import static datadog.trace.api.Config.HEADER_TAGS
|
||||
import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED
|
||||
import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_HOST
|
||||
import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT
|
||||
|
|
@ -21,8 +20,6 @@ import static datadog.trace.api.Config.HTTP_SERVER_ERROR_STATUSES
|
|||
import static datadog.trace.api.Config.JMX_TAGS
|
||||
import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS
|
||||
import static datadog.trace.api.Config.PREFIX
|
||||
import static datadog.trace.api.Config.PROPAGATION_STYLE_EXTRACT
|
||||
import static datadog.trace.api.Config.PROPAGATION_STYLE_INJECT
|
||||
import static datadog.trace.api.Config.RUNTIME_CONTEXT_FIELD_INJECTION
|
||||
import static datadog.trace.api.Config.RUNTIME_ID_TAG
|
||||
import static datadog.trace.api.Config.SERVICE_NAME
|
||||
|
|
@ -44,9 +41,6 @@ class ConfigTest extends DDSpecification {
|
|||
private static final DD_TRACE_ENABLED_ENV = "DD_TRACE_ENABLED"
|
||||
private static final DD_WRITER_TYPE_ENV = "DD_WRITER_TYPE"
|
||||
private static final DD_SPAN_TAGS_ENV = "DD_SPAN_TAGS"
|
||||
private static final DD_HEADER_TAGS_ENV = "DD_HEADER_TAGS"
|
||||
private static final DD_PROPAGATION_STYLE_EXTRACT = "DD_PROPAGATION_STYLE_EXTRACT"
|
||||
private static final DD_PROPAGATION_STYLE_INJECT = "DD_PROPAGATION_STYLE_INJECT"
|
||||
private static final DD_TRACE_AGENT_PORT_ENV = "DD_TRACE_AGENT_PORT"
|
||||
private static final DD_AGENT_PORT_LEGACY_ENV = "DD_AGENT_PORT"
|
||||
private static final DD_TRACE_REPORT_HOSTNAME = "DD_TRACE_REPORT_HOSTNAME"
|
||||
|
|
@ -65,7 +59,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.traceResolverEnabled == true
|
||||
config.mergedSpanTags == [:]
|
||||
config.mergedJmxTags == [(RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName]
|
||||
config.headerTags == [:]
|
||||
config.httpServerErrorStatuses == (500..599).toSet()
|
||||
config.httpClientErrorStatuses == (400..499).toSet()
|
||||
config.httpClientSplitByDomain == false
|
||||
|
|
@ -73,8 +66,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.partialFlushMinSpans == 1000
|
||||
config.reportHostName == false
|
||||
config.runtimeContextFieldInjection == true
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG]
|
||||
config.healthMetricsEnabled == false
|
||||
config.healthMetricsStatsdHost == null
|
||||
config.healthMetricsStatsdPort == null
|
||||
|
|
@ -102,7 +93,6 @@ class ConfigTest extends DDSpecification {
|
|||
prop.setProperty(GLOBAL_TAGS, "b:2")
|
||||
prop.setProperty(SPAN_TAGS, "c:3")
|
||||
prop.setProperty(JMX_TAGS, "d:4")
|
||||
prop.setProperty(HEADER_TAGS, "e:5")
|
||||
prop.setProperty(HTTP_SERVER_ERROR_STATUSES, "123-456,457,124-125,122")
|
||||
prop.setProperty(HTTP_CLIENT_ERROR_STATUSES, "111")
|
||||
prop.setProperty(HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
|
||||
|
|
@ -110,8 +100,6 @@ class ConfigTest extends DDSpecification {
|
|||
prop.setProperty(PARTIAL_FLUSH_MIN_SPANS, "15")
|
||||
prop.setProperty(TRACE_REPORT_HOSTNAME, "true")
|
||||
prop.setProperty(RUNTIME_CONTEXT_FIELD_INJECTION, "false")
|
||||
prop.setProperty(PROPAGATION_STYLE_EXTRACT, "Datadog, B3")
|
||||
prop.setProperty(PROPAGATION_STYLE_INJECT, "B3, Datadog")
|
||||
prop.setProperty(HEALTH_METRICS_ENABLED, "true")
|
||||
prop.setProperty(HEALTH_METRICS_STATSD_HOST, "metrics statsd host")
|
||||
prop.setProperty(HEALTH_METRICS_STATSD_PORT, "654")
|
||||
|
|
@ -129,7 +117,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.traceResolverEnabled == false
|
||||
config.mergedSpanTags == [b: "2", c: "3"]
|
||||
config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName]
|
||||
config.headerTags == [e: "5"]
|
||||
config.httpServerErrorStatuses == (122..457).toSet()
|
||||
config.httpClientErrorStatuses == (111..111).toSet()
|
||||
config.httpClientSplitByDomain == true
|
||||
|
|
@ -137,8 +124,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.partialFlushMinSpans == 15
|
||||
config.reportHostName == true
|
||||
config.runtimeContextFieldInjection == false
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
|
||||
config.healthMetricsEnabled == true
|
||||
config.healthMetricsStatsdHost == "metrics statsd host"
|
||||
config.healthMetricsStatsdPort == 654
|
||||
|
|
@ -157,7 +142,6 @@ class ConfigTest extends DDSpecification {
|
|||
System.setProperty(PREFIX + GLOBAL_TAGS, "b:2")
|
||||
System.setProperty(PREFIX + SPAN_TAGS, "c:3")
|
||||
System.setProperty(PREFIX + JMX_TAGS, "d:4")
|
||||
System.setProperty(PREFIX + HEADER_TAGS, "e:5")
|
||||
System.setProperty(PREFIX + HTTP_SERVER_ERROR_STATUSES, "123-456,457,124-125,122")
|
||||
System.setProperty(PREFIX + HTTP_CLIENT_ERROR_STATUSES, "111")
|
||||
System.setProperty(PREFIX + HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
|
||||
|
|
@ -165,8 +149,6 @@ class ConfigTest extends DDSpecification {
|
|||
System.setProperty(PREFIX + PARTIAL_FLUSH_MIN_SPANS, "25")
|
||||
System.setProperty(PREFIX + TRACE_REPORT_HOSTNAME, "true")
|
||||
System.setProperty(PREFIX + RUNTIME_CONTEXT_FIELD_INJECTION, "false")
|
||||
System.setProperty(PREFIX + PROPAGATION_STYLE_EXTRACT, "Datadog, B3")
|
||||
System.setProperty(PREFIX + PROPAGATION_STYLE_INJECT, "B3, Datadog")
|
||||
System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true")
|
||||
System.setProperty(PREFIX + HEALTH_METRICS_STATSD_HOST, "metrics statsd host")
|
||||
System.setProperty(PREFIX + HEALTH_METRICS_STATSD_PORT, "654")
|
||||
|
|
@ -184,7 +166,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.traceResolverEnabled == false
|
||||
config.mergedSpanTags == [b: "2", c: "3"]
|
||||
config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName]
|
||||
config.headerTags == [e: "5"]
|
||||
config.httpServerErrorStatuses == (122..457).toSet()
|
||||
config.httpClientErrorStatuses == (111..111).toSet()
|
||||
config.httpClientSplitByDomain == true
|
||||
|
|
@ -192,8 +173,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.partialFlushMinSpans == 25
|
||||
config.reportHostName == true
|
||||
config.runtimeContextFieldInjection == false
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
|
||||
config.healthMetricsEnabled == true
|
||||
config.healthMetricsStatsdHost == "metrics statsd host"
|
||||
config.healthMetricsStatsdPort == 654
|
||||
|
|
@ -204,8 +183,6 @@ class ConfigTest extends DDSpecification {
|
|||
environmentVariables.set(DD_SERVICE_NAME_ENV, "still something else")
|
||||
environmentVariables.set(DD_TRACE_ENABLED_ENV, "false")
|
||||
environmentVariables.set(DD_WRITER_TYPE_ENV, "LoggingWriter")
|
||||
environmentVariables.set(DD_PROPAGATION_STYLE_EXTRACT, "B3 Datadog")
|
||||
environmentVariables.set(DD_PROPAGATION_STYLE_INJECT, "Datadog B3")
|
||||
environmentVariables.set(DD_TRACE_REPORT_HOSTNAME, "true")
|
||||
|
||||
when:
|
||||
|
|
@ -215,8 +192,6 @@ class ConfigTest extends DDSpecification {
|
|||
config.serviceName == "still something else"
|
||||
config.traceEnabled == false
|
||||
config.writerType == "LoggingWriter"
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]
|
||||
config.reportHostName == true
|
||||
}
|
||||
|
||||
|
|
@ -250,14 +225,11 @@ class ConfigTest extends DDSpecification {
|
|||
System.setProperty(PREFIX + TRACE_AGENT_PORT, " ")
|
||||
System.setProperty(PREFIX + AGENT_PORT_LEGACY, "invalid")
|
||||
System.setProperty(PREFIX + TRACE_RESOLVER_ENABLED, " ")
|
||||
System.setProperty(PREFIX + HEADER_TAGS, "1")
|
||||
System.setProperty(PREFIX + SPAN_TAGS, "invalid")
|
||||
System.setProperty(PREFIX + HTTP_SERVER_ERROR_STATUSES, "1111")
|
||||
System.setProperty(PREFIX + HTTP_CLIENT_ERROR_STATUSES, "1:1")
|
||||
System.setProperty(PREFIX + HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "invalid")
|
||||
System.setProperty(PREFIX + DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "invalid")
|
||||
System.setProperty(PREFIX + PROPAGATION_STYLE_EXTRACT, "some garbage")
|
||||
System.setProperty(PREFIX + PROPAGATION_STYLE_INJECT, " ")
|
||||
|
||||
when:
|
||||
def config = new Config()
|
||||
|
|
@ -270,13 +242,10 @@ class ConfigTest extends DDSpecification {
|
|||
config.agentPort == 8126
|
||||
config.traceResolverEnabled == true
|
||||
config.mergedSpanTags == [:]
|
||||
config.headerTags == [:]
|
||||
config.httpServerErrorStatuses == (500..599).toSet()
|
||||
config.httpClientErrorStatuses == (400..499).toSet()
|
||||
config.httpClientSplitByDomain == false
|
||||
config.dbClientSplitByInstance == false
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG]
|
||||
}
|
||||
|
||||
def "sys props and env vars overrides for trace_agent_port and agent_port_legacy as expected"() {
|
||||
|
|
@ -334,14 +303,11 @@ class ConfigTest extends DDSpecification {
|
|||
properties.setProperty(GLOBAL_TAGS, "b:2")
|
||||
properties.setProperty(SPAN_TAGS, "c:3")
|
||||
properties.setProperty(JMX_TAGS, "d:4")
|
||||
properties.setProperty(HEADER_TAGS, "e:5")
|
||||
properties.setProperty(HTTP_SERVER_ERROR_STATUSES, "123-456,457,124-125,122")
|
||||
properties.setProperty(HTTP_CLIENT_ERROR_STATUSES, "111")
|
||||
properties.setProperty(HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
|
||||
properties.setProperty(DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "true")
|
||||
properties.setProperty(PARTIAL_FLUSH_MIN_SPANS, "15")
|
||||
properties.setProperty(PROPAGATION_STYLE_EXTRACT, "B3 Datadog")
|
||||
properties.setProperty(PROPAGATION_STYLE_INJECT, "Datadog B3")
|
||||
|
||||
when:
|
||||
def config = Config.get(properties)
|
||||
|
|
@ -356,14 +322,11 @@ class ConfigTest extends DDSpecification {
|
|||
config.traceResolverEnabled == false
|
||||
config.mergedSpanTags == [b: "2", c: "3"]
|
||||
config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName]
|
||||
config.headerTags == [e: "5"]
|
||||
config.httpServerErrorStatuses == (122..457).toSet()
|
||||
config.httpClientErrorStatuses == (111..111).toSet()
|
||||
config.httpClientSplitByDomain == true
|
||||
config.dbClientSplitByInstance == true
|
||||
config.partialFlushMinSpans == 15
|
||||
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
|
||||
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]
|
||||
}
|
||||
|
||||
def "override null properties"() {
|
||||
|
|
@ -466,10 +429,8 @@ class ConfigTest extends DDSpecification {
|
|||
def "verify mapping configs on tracer"() {
|
||||
setup:
|
||||
System.setProperty(PREFIX + SPAN_TAGS, mapString)
|
||||
System.setProperty(PREFIX + HEADER_TAGS, mapString)
|
||||
def props = new Properties()
|
||||
props.setProperty(SPAN_TAGS, mapString)
|
||||
props.setProperty(HEADER_TAGS, mapString)
|
||||
|
||||
when:
|
||||
def config = new Config()
|
||||
|
|
@ -477,9 +438,7 @@ class ConfigTest extends DDSpecification {
|
|||
|
||||
then:
|
||||
config.spanTags == map
|
||||
config.headerTags == map
|
||||
propConfig.spanTags == map
|
||||
propConfig.headerTags == map
|
||||
|
||||
where:
|
||||
mapString | map
|
||||
|
|
@ -545,14 +504,12 @@ class ConfigTest extends DDSpecification {
|
|||
def "verify null value mapping configs on tracer"() {
|
||||
setup:
|
||||
environmentVariables.set(DD_SPAN_TAGS_ENV, mapString)
|
||||
environmentVariables.set(DD_HEADER_TAGS_ENV, mapString)
|
||||
|
||||
when:
|
||||
def config = new Config()
|
||||
|
||||
then:
|
||||
config.spanTags == map
|
||||
config.headerTags == map
|
||||
|
||||
where:
|
||||
mapString | map
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ public class DDSpan implements Span {
|
|||
*/
|
||||
@Override
|
||||
public final String getBaggageItem(final String key) {
|
||||
return context.getBaggageItem(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
@ -206,7 +206,6 @@ public class DDSpan implements Span {
|
|||
*/
|
||||
@Override
|
||||
public final DDSpan setBaggageItem(final String key, final String value) {
|
||||
context.setBaggageItem(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -277,16 +276,13 @@ public class DDSpan implements Span {
|
|||
// Getters and JSON serialisation instructions
|
||||
|
||||
/**
|
||||
* Meta merges baggage and tags (stringified values)
|
||||
* Stringified tags
|
||||
*
|
||||
* @return merged context baggage and tags
|
||||
* @return stringified tags
|
||||
*/
|
||||
@JsonGetter
|
||||
public Map<String, String> getMeta() {
|
||||
final Map<String, String> meta = new HashMap<>();
|
||||
for (final Map.Entry<String, String> entry : context().getBaggageItems().entrySet()) {
|
||||
meta.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
for (final Map.Entry<String, Object> entry : getTags().entrySet()) {
|
||||
meta.put(entry.getKey(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* SpanContext represents Span state that must propagate to descendant Spans and across process
|
||||
* boundaries.
|
||||
*
|
||||
* <p>SpanContext is logically divided into two pieces: (1) the user-level "Baggage" that propagates
|
||||
* across Span boundaries and (2) any Datadog fields that are needed to identify or contextualize
|
||||
* the associated Span instance
|
||||
* <p>SpanContext includes Datadog fields that are needed to identify or contextualize the
|
||||
* associated Span instance
|
||||
*/
|
||||
@Slf4j
|
||||
public class DDSpanContext implements io.opentracing.SpanContext {
|
||||
public static final String ORIGIN_KEY = "_dd.origin";
|
||||
|
||||
private static final Map<String, Number> EMPTY_METRICS = Collections.emptyMap();
|
||||
|
||||
|
|
@ -33,9 +31,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
/** The collection of all span related to this one */
|
||||
private final PendingTrace trace;
|
||||
|
||||
/** Baggage is associated with the whole trace and shared with other spans */
|
||||
private final Map<String, String> baggageItems;
|
||||
|
||||
// Not Shared with other span contexts
|
||||
private final BigInteger traceId;
|
||||
private final BigInteger spanId;
|
||||
|
|
@ -54,8 +49,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
private volatile String spanType;
|
||||
/** True indicates that the span reports an error */
|
||||
private volatile boolean errorFlag;
|
||||
/** The origin of the trace. (eg. Synthetics) */
|
||||
private final String origin;
|
||||
/** Metrics on the span */
|
||||
private final AtomicReference<Map<String, Number>> metrics = new AtomicReference<>();
|
||||
|
||||
|
|
@ -70,8 +63,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
final String serviceName,
|
||||
final String operationName,
|
||||
final String resourceName,
|
||||
final String origin,
|
||||
final Map<String, String> baggageItems,
|
||||
final boolean errorFlag,
|
||||
final String spanType,
|
||||
final Map<String, Object> tags,
|
||||
|
|
@ -90,12 +81,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
this.spanId = spanId;
|
||||
this.parentId = parentId;
|
||||
|
||||
if (baggageItems == null) {
|
||||
this.baggageItems = new ConcurrentHashMap<>(0);
|
||||
} else {
|
||||
this.baggageItems = new ConcurrentHashMap<>(baggageItems);
|
||||
}
|
||||
|
||||
if (tags != null) {
|
||||
this.tags.putAll(tags);
|
||||
}
|
||||
|
|
@ -105,11 +90,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
this.resourceName = resourceName;
|
||||
this.errorFlag = errorFlag;
|
||||
this.spanType = spanType;
|
||||
this.origin = origin;
|
||||
|
||||
if (origin != null) {
|
||||
this.tags.put(ORIGIN_KEY, origin);
|
||||
}
|
||||
this.tags.put(DDTags.THREAD_NAME, threadName);
|
||||
this.tags.put(DDTags.THREAD_ID, threadId);
|
||||
}
|
||||
|
|
@ -176,33 +157,12 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
this.spanType = spanType;
|
||||
}
|
||||
|
||||
public String getOrigin() {
|
||||
final DDSpan rootSpan = trace.getRootSpan();
|
||||
if (null != rootSpan) {
|
||||
return rootSpan.context().origin;
|
||||
} else {
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBaggageItem(final String key, final String value) {
|
||||
baggageItems.put(key, value);
|
||||
}
|
||||
|
||||
public String getBaggageItem(final String key) {
|
||||
return baggageItems.get(key);
|
||||
}
|
||||
|
||||
public Map<String, String> getBaggageItems() {
|
||||
return baggageItems;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see io.opentracing.SpanContext#baggageItems()
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, String>> baggageItems() {
|
||||
return baggageItems.entrySet();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import datadog.opentracing.decorators.AbstractDecorator;
|
|||
import datadog.opentracing.decorators.DDDecoratorsFactory;
|
||||
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;
|
||||
import datadog.trace.api.Config;
|
||||
|
|
@ -98,20 +97,13 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
Writer.Builder.forConfig(config),
|
||||
config.getLocalRootSpanTags(),
|
||||
config.getMergedSpanTags(),
|
||||
config.getHeaderTags(),
|
||||
config.getPartialFlushMinSpans());
|
||||
log.debug("Using config: {}", config);
|
||||
}
|
||||
|
||||
/** Visible for testing */
|
||||
DDTracer(final String serviceName, final Writer writer, final Map<String, String> runtimeTags) {
|
||||
this(
|
||||
serviceName,
|
||||
writer,
|
||||
runtimeTags,
|
||||
Collections.<String, String>emptyMap(),
|
||||
Collections.<String, String>emptyMap(),
|
||||
0);
|
||||
this(serviceName, writer, runtimeTags, Collections.<String, String>emptyMap(), 0);
|
||||
}
|
||||
|
||||
public DDTracer(final Writer writer) {
|
||||
|
|
@ -124,42 +116,37 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
writer,
|
||||
config.getLocalRootSpanTags(),
|
||||
config.getMergedSpanTags(),
|
||||
config.getHeaderTags(),
|
||||
config.getPartialFlushMinSpans());
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #DDTracer(String, Writer, Map, Map, Map, int)} instead. */
|
||||
/** @deprecated Use {@link #DDTracer(String, Writer, Map, Map, int)} instead. */
|
||||
@Deprecated
|
||||
public DDTracer(
|
||||
final String serviceName,
|
||||
final Writer writer,
|
||||
final String runtimeId,
|
||||
final Map<String, String> localRootSpanTags,
|
||||
final Map<String, String> defaultSpanTags,
|
||||
final Map<String, String> taggedHeaders) {
|
||||
final Map<String, String> defaultSpanTags) {
|
||||
this(
|
||||
serviceName,
|
||||
writer,
|
||||
customRuntimeTags(runtimeId, localRootSpanTags),
|
||||
defaultSpanTags,
|
||||
taggedHeaders,
|
||||
Config.get().getPartialFlushMinSpans());
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #DDTracer(String, Writer, Map, Map, Map, int)} instead. */
|
||||
/** @deprecated Use {@link #DDTracer(String, Writer, Map, Map,int)} instead. */
|
||||
@Deprecated
|
||||
public DDTracer(
|
||||
final String serviceName,
|
||||
final Writer writer,
|
||||
final Map<String, String> localRootSpanTags,
|
||||
final Map<String, String> defaultSpanTags,
|
||||
final Map<String, String> taggedHeaders) {
|
||||
final Map<String, String> defaultSpanTags) {
|
||||
this(
|
||||
serviceName,
|
||||
writer,
|
||||
localRootSpanTags,
|
||||
defaultSpanTags,
|
||||
taggedHeaders,
|
||||
Config.get().getPartialFlushMinSpans());
|
||||
}
|
||||
|
||||
|
|
@ -168,11 +155,9 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
final Writer writer,
|
||||
final Map<String, String> localRootSpanTags,
|
||||
final Map<String, String> defaultSpanTags,
|
||||
final Map<String, String> taggedHeaders,
|
||||
final int partialFlushMinSpans) {
|
||||
assert localRootSpanTags != null;
|
||||
assert defaultSpanTags != null;
|
||||
assert taggedHeaders != null;
|
||||
|
||||
this.serviceName = serviceName;
|
||||
this.writer = writer;
|
||||
|
|
@ -189,8 +174,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
}
|
||||
|
||||
// TODO: we have too many constructors, we should move to some sort of builder approach
|
||||
injector = HttpCodec.createInjector(Config.get());
|
||||
extractor = HttpCodec.createExtractor(Config.get(), taggedHeaders);
|
||||
injector = HttpCodec.createInjector();
|
||||
extractor = HttpCodec.createExtractor();
|
||||
|
||||
log.info("New instance: {}", this);
|
||||
|
||||
|
|
@ -453,13 +438,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
return this;
|
||||
}
|
||||
|
||||
public Iterable<Map.Entry<String, String>> baggageItems() {
|
||||
if (parent == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return parent.baggageItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DDSpanBuilder asChildOf(final Span span) {
|
||||
return asChildOf(span == null ? null : span.context());
|
||||
|
|
@ -514,7 +492,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
|
||||
/**
|
||||
* Build the SpanContext, if the actual span has a parent, the following attributes must be
|
||||
* propagated: - ServiceName - Baggage - Trace (a list of all spans related) - SpanType
|
||||
* propagated: - ServiceName - Trace (a list of all spans related) - SpanType
|
||||
*
|
||||
* @return the context
|
||||
*/
|
||||
|
|
@ -522,9 +500,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
final BigInteger traceId;
|
||||
final BigInteger spanId = generateNewId();
|
||||
final BigInteger parentSpanId;
|
||||
final Map<String, String> baggage;
|
||||
final PendingTrace parentTrace;
|
||||
final String origin;
|
||||
|
||||
final DDSpanContext context;
|
||||
SpanContext parentContext = parent;
|
||||
|
|
@ -543,9 +519,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
final DDSpanContext ddsc = (DDSpanContext) parentContext;
|
||||
traceId = ddsc.getTraceId();
|
||||
parentSpanId = ddsc.getSpanId();
|
||||
baggage = ddsc.getBaggageItems();
|
||||
parentTrace = ddsc.getTrace();
|
||||
origin = null;
|
||||
if (serviceName == null) {
|
||||
serviceName = ddsc.getServiceName();
|
||||
}
|
||||
|
|
@ -556,20 +530,10 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
final ExtractedContext extractedContext = (ExtractedContext) parentContext;
|
||||
traceId = extractedContext.getTraceId();
|
||||
parentSpanId = extractedContext.getSpanId();
|
||||
baggage = extractedContext.getBaggage();
|
||||
} else {
|
||||
// Start a new trace
|
||||
traceId = generateNewId();
|
||||
parentSpanId = BigInteger.ZERO;
|
||||
baggage = null;
|
||||
}
|
||||
|
||||
// Get header tags and set origin whether propagating or not.
|
||||
if (parentContext instanceof TagContext) {
|
||||
tags.putAll(((TagContext) parentContext).getTags());
|
||||
origin = ((TagContext) parentContext).getOrigin();
|
||||
} else {
|
||||
origin = null;
|
||||
}
|
||||
|
||||
tags.putAll(localRootSpanTags);
|
||||
|
|
@ -592,8 +556,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
|||
serviceName,
|
||||
operationName,
|
||||
resourceName,
|
||||
origin,
|
||||
baggage,
|
||||
errorFlag,
|
||||
spanType,
|
||||
tags,
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import static datadog.opentracing.propagation.HttpCodec.validateUInt64BitsID;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMapExtract;
|
||||
import io.opentracing.propagation.TextMapInject;
|
||||
import java.math.BigInteger;
|
||||
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 using B3 headers
|
||||
*
|
||||
* <p>TODO: there is fair amount of code duplication between DatadogHttpCodec and this class,
|
||||
* especially in part where TagContext is handled. We may want to refactor that and avoid special
|
||||
* handling of TagContext in other places (i.e. CompoundExtractor).
|
||||
*/
|
||||
@Slf4j
|
||||
class B3HttpCodec {
|
||||
|
||||
private static final String TRACE_ID_KEY = "X-B3-TraceId";
|
||||
private static final String SPAN_ID_KEY = "X-B3-SpanId";
|
||||
private static final int HEX_RADIX = 16;
|
||||
|
||||
private B3HttpCodec() {
|
||||
// This class should not be created. This also makes code coverage checks happy.
|
||||
}
|
||||
|
||||
public static class Injector implements HttpCodec.Injector {
|
||||
|
||||
@Override
|
||||
public void inject(final DDSpanContext context, final TextMapInject carrier) {
|
||||
try {
|
||||
carrier.put(TRACE_ID_KEY, context.getTraceId().toString(HEX_RADIX).toLowerCase());
|
||||
carrier.put(SPAN_ID_KEY, context.getSpanId().toString(HEX_RADIX).toLowerCase());
|
||||
log.debug("{} - B3 parent context injected", context.getTraceId());
|
||||
} catch (final NumberFormatException e) {
|
||||
log.debug(
|
||||
"Cannot parse context id(s): {} {}", context.getTraceId(), context.getSpanId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extractor implements HttpCodec.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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanContext extract(final TextMapExtract carrier) {
|
||||
try {
|
||||
Map<String, String> tags = Collections.emptyMap();
|
||||
BigInteger traceId = BigInteger.ZERO;
|
||||
BigInteger spanId = BigInteger.ZERO;
|
||||
|
||||
for (final Map.Entry<String, String> entry : carrier) {
|
||||
final String key = entry.getKey().toLowerCase();
|
||||
final String value = entry.getValue();
|
||||
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
|
||||
final String trimmedValue;
|
||||
final int length = value.length();
|
||||
if (length > 32) {
|
||||
log.debug("Header {} exceeded max length of 32: {}", TRACE_ID_KEY, value);
|
||||
traceId = BigInteger.ZERO;
|
||||
continue;
|
||||
} else if (length > 16) {
|
||||
trimmedValue = value.substring(length - 16);
|
||||
} else {
|
||||
trimmedValue = value;
|
||||
}
|
||||
traceId = validateUInt64BitsID(trimmedValue, HEX_RADIX);
|
||||
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
|
||||
spanId = validateUInt64BitsID(value, HEX_RADIX);
|
||||
}
|
||||
|
||||
if (taggedHeaders.containsKey(key)) {
|
||||
if (tags.isEmpty()) {
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
tags.put(taggedHeaders.get(key), HttpCodec.decode(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (!BigInteger.ZERO.equals(traceId)) {
|
||||
final ExtractedContext context =
|
||||
new ExtractedContext(
|
||||
traceId, spanId, null, Collections.<String, String>emptyMap(), tags);
|
||||
|
||||
log.debug("{} - Parent context extracted", context.getTraceId());
|
||||
return context;
|
||||
} else if (!tags.isEmpty()) {
|
||||
log.debug("Tags context extracted");
|
||||
return new TagContext(null, tags);
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
log.debug("Exception when extracting context", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,9 @@ package datadog.opentracing.propagation;
|
|||
import static datadog.opentracing.propagation.HttpCodec.validateUInt64BitsID;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMapExtract;
|
||||
import io.opentracing.propagation.TextMapInject;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
|
@ -16,10 +13,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||
@Slf4j
|
||||
class DatadogHttpCodec {
|
||||
|
||||
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 ORIGIN_KEY = "x-datadog-origin";
|
||||
|
||||
private DatadogHttpCodec() {
|
||||
// This class should not be created. This also makes code coverage checks happy.
|
||||
|
|
@ -31,36 +26,20 @@ class DatadogHttpCodec {
|
|||
public void inject(final DDSpanContext context, final TextMapInject carrier) {
|
||||
carrier.put(TRACE_ID_KEY, context.getTraceId().toString());
|
||||
carrier.put(SPAN_ID_KEY, context.getSpanId().toString());
|
||||
final String origin = context.getOrigin();
|
||||
if (origin != null) {
|
||||
carrier.put(ORIGIN_KEY, origin);
|
||||
}
|
||||
|
||||
for (final Map.Entry<String, String> entry : context.baggageItems()) {
|
||||
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), HttpCodec.encode(entry.getValue()));
|
||||
}
|
||||
log.debug("{} - Datadog parent context injected", context.getTraceId());
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extractor implements HttpCodec.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 Extractor() {}
|
||||
|
||||
@Override
|
||||
public SpanContext extract(final TextMapExtract carrier) {
|
||||
public ExtractedContext extract(final TextMapExtract carrier) {
|
||||
try {
|
||||
Map<String, String> baggage = Collections.emptyMap();
|
||||
Map<String, String> tags = Collections.emptyMap();
|
||||
BigInteger traceId = BigInteger.ZERO;
|
||||
BigInteger spanId = BigInteger.ZERO;
|
||||
String origin = null;
|
||||
|
||||
for (final Map.Entry<String, String> entry : carrier) {
|
||||
final String key = entry.getKey().toLowerCase();
|
||||
|
|
@ -74,32 +53,14 @@ class DatadogHttpCodec {
|
|||
traceId = validateUInt64BitsID(value, 10);
|
||||
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
|
||||
spanId = validateUInt64BitsID(value, 10);
|
||||
} else if (ORIGIN_KEY.equalsIgnoreCase(key)) {
|
||||
origin = value;
|
||||
} else if (key.startsWith(OT_BAGGAGE_PREFIX)) {
|
||||
if (baggage.isEmpty()) {
|
||||
baggage = new HashMap<>();
|
||||
}
|
||||
baggage.put(key.replace(OT_BAGGAGE_PREFIX, ""), HttpCodec.decode(value));
|
||||
}
|
||||
|
||||
if (taggedHeaders.containsKey(key)) {
|
||||
if (tags.isEmpty()) {
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
tags.put(taggedHeaders.get(key), HttpCodec.decode(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (!BigInteger.ZERO.equals(traceId)) {
|
||||
final ExtractedContext context =
|
||||
new ExtractedContext(traceId, spanId, origin, baggage, tags);
|
||||
final ExtractedContext context = new ExtractedContext(traceId, spanId);
|
||||
|
||||
log.debug("{} - Parent context extracted", context.getTraceId());
|
||||
return context;
|
||||
} else if (origin != null || !tags.isEmpty()) {
|
||||
log.debug("Tags context extracted");
|
||||
return new TagContext(origin, tags);
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
log.debug("Exception when extracting context", e);
|
||||
|
|
|
|||
|
|
@ -1,31 +1,35 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import io.opentracing.SpanContext;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Propagated data resulting from calling tracer.extract with header data from an incoming request.
|
||||
*/
|
||||
public class ExtractedContext extends TagContext {
|
||||
public class ExtractedContext implements SpanContext {
|
||||
private final BigInteger traceId;
|
||||
private final BigInteger spanId;
|
||||
private final Map<String, String> baggage;
|
||||
|
||||
public ExtractedContext(
|
||||
final BigInteger traceId,
|
||||
final BigInteger spanId,
|
||||
final String origin,
|
||||
final Map<String, String> baggage,
|
||||
final Map<String, String> tags) {
|
||||
super(origin, tags);
|
||||
public ExtractedContext(final BigInteger traceId, final BigInteger spanId) {
|
||||
this.traceId = traceId;
|
||||
this.spanId = spanId;
|
||||
this.baggage = baggage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toTraceId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSpanId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, String>> baggageItems() {
|
||||
return baggage.entrySet();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public BigInteger getTraceId() {
|
||||
|
|
@ -35,8 +39,4 @@ public class ExtractedContext extends TagContext {
|
|||
public BigInteger getSpanId() {
|
||||
return spanId;
|
||||
}
|
||||
|
||||
public Map<String, String> getBaggage() {
|
||||
return baggage;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import static datadog.opentracing.propagation.HttpCodec.validateUInt64BitsID;
|
||||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMapExtract;
|
||||
import io.opentracing.propagation.TextMapInject;
|
||||
import java.math.BigInteger;
|
||||
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 using Haystack headers.
|
||||
*
|
||||
* @author Alex Antonov
|
||||
*/
|
||||
@Slf4j
|
||||
public class HaystackHttpCodec {
|
||||
|
||||
private static final String OT_BAGGAGE_PREFIX = "Baggage-";
|
||||
private static final String TRACE_ID_KEY = "Trace-ID";
|
||||
private static final String SPAN_ID_KEY = "Span-ID";
|
||||
private static final String PARENT_ID_KEY = "Parent_ID";
|
||||
|
||||
private HaystackHttpCodec() {
|
||||
// This class should not be created. This also makes code coverage checks happy.
|
||||
}
|
||||
|
||||
public static class Injector implements HttpCodec.Injector {
|
||||
|
||||
@Override
|
||||
public void inject(final DDSpanContext context, final TextMapInject carrier) {
|
||||
carrier.put(TRACE_ID_KEY, context.getTraceId().toString());
|
||||
carrier.put(SPAN_ID_KEY, context.getSpanId().toString());
|
||||
carrier.put(PARENT_ID_KEY, context.getParentId().toString());
|
||||
|
||||
for (final Map.Entry<String, String> entry : context.baggageItems()) {
|
||||
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), HttpCodec.encode(entry.getValue()));
|
||||
}
|
||||
log.debug("{} - Haystack parent context injected", context.getTraceId());
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extractor implements HttpCodec.Extractor {
|
||||
private final Map<String, String> taggedHeaders;
|
||||
|
||||
/** Creates Header Extractor using Haystack propagation. */
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanContext extract(final TextMapExtract carrier) {
|
||||
try {
|
||||
Map<String, String> baggage = Collections.emptyMap();
|
||||
Map<String, String> tags = Collections.emptyMap();
|
||||
BigInteger traceId = BigInteger.ZERO;
|
||||
BigInteger spanId = BigInteger.ZERO;
|
||||
final String origin = null; // Always null
|
||||
|
||||
for (final Map.Entry<String, String> entry : carrier) {
|
||||
final String key = entry.getKey().toLowerCase();
|
||||
final String value = entry.getValue();
|
||||
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TRACE_ID_KEY.equalsIgnoreCase(key)) {
|
||||
traceId = validateUInt64BitsID(value, 10);
|
||||
} else if (SPAN_ID_KEY.equalsIgnoreCase(key)) {
|
||||
spanId = validateUInt64BitsID(value, 10);
|
||||
} else if (key.startsWith(OT_BAGGAGE_PREFIX.toLowerCase())) {
|
||||
if (baggage.isEmpty()) {
|
||||
baggage = new HashMap<>();
|
||||
}
|
||||
baggage.put(key.replace(OT_BAGGAGE_PREFIX.toLowerCase(), ""), HttpCodec.decode(value));
|
||||
}
|
||||
|
||||
if (taggedHeaders.containsKey(key)) {
|
||||
if (tags.isEmpty()) {
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
tags.put(taggedHeaders.get(key), HttpCodec.decode(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (!BigInteger.ZERO.equals(traceId)) {
|
||||
final ExtractedContext context =
|
||||
new ExtractedContext(traceId, spanId, origin, baggage, tags);
|
||||
|
||||
log.debug("{} - Parent context extracted", context.getTraceId());
|
||||
return context;
|
||||
} else if (origin != null || !tags.isEmpty()) {
|
||||
log.debug("Tags context extracted");
|
||||
return new TagContext(origin, tags);
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
log.debug("Exception when extracting context", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,17 +2,9 @@ package datadog.opentracing.propagation;
|
|||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import datadog.opentracing.DDTracer;
|
||||
import datadog.trace.api.Config;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.TextMapExtract;
|
||||
import io.opentracing.propagation.TextMapInject;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -24,86 +16,15 @@ public class HttpCodec {
|
|||
|
||||
public interface Extractor {
|
||||
|
||||
SpanContext extract(final TextMapExtract carrier);
|
||||
ExtractedContext extract(final TextMapExtract carrier);
|
||||
}
|
||||
|
||||
public static Injector createInjector(final Config config) {
|
||||
final List<Injector> injectors = new ArrayList<>();
|
||||
for (final Config.PropagationStyle style : config.getPropagationStylesToInject()) {
|
||||
if (style == Config.PropagationStyle.DATADOG) {
|
||||
injectors.add(new DatadogHttpCodec.Injector());
|
||||
continue;
|
||||
}
|
||||
if (style == Config.PropagationStyle.B3) {
|
||||
injectors.add(new B3HttpCodec.Injector());
|
||||
continue;
|
||||
}
|
||||
if (style == Config.PropagationStyle.HAYSTACK) {
|
||||
injectors.add(new HaystackHttpCodec.Injector());
|
||||
continue;
|
||||
}
|
||||
log.debug("No implementation found to inject propagation style: {}", style);
|
||||
}
|
||||
return new CompoundInjector(injectors);
|
||||
public static Injector createInjector() {
|
||||
return new DatadogHttpCodec.Injector();
|
||||
}
|
||||
|
||||
public static Extractor createExtractor(
|
||||
final Config config, final Map<String, String> taggedHeaders) {
|
||||
final List<Extractor> extractors = new ArrayList<>();
|
||||
for (final Config.PropagationStyle style : config.getPropagationStylesToExtract()) {
|
||||
if (style == Config.PropagationStyle.DATADOG) {
|
||||
extractors.add(new DatadogHttpCodec.Extractor(taggedHeaders));
|
||||
continue;
|
||||
}
|
||||
if (style == Config.PropagationStyle.B3) {
|
||||
extractors.add(new B3HttpCodec.Extractor(taggedHeaders));
|
||||
continue;
|
||||
}
|
||||
if (style == Config.PropagationStyle.HAYSTACK) {
|
||||
extractors.add(new HaystackHttpCodec.Extractor(taggedHeaders));
|
||||
continue;
|
||||
}
|
||||
log.debug("No implementation found to extract propagation style: {}", style);
|
||||
}
|
||||
return new CompoundExtractor(extractors);
|
||||
}
|
||||
|
||||
public static class CompoundInjector implements Injector {
|
||||
|
||||
private final List<Injector> injectors;
|
||||
|
||||
public CompoundInjector(final List<Injector> injectors) {
|
||||
this.injectors = injectors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(final DDSpanContext context, final TextMapInject carrier) {
|
||||
for (final Injector injector : injectors) {
|
||||
injector.inject(context, carrier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompoundExtractor implements Extractor {
|
||||
|
||||
private final List<Extractor> extractors;
|
||||
|
||||
public CompoundExtractor(final List<Extractor> extractors) {
|
||||
this.extractors = extractors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanContext extract(final TextMapExtract carrier) {
|
||||
SpanContext context = null;
|
||||
for (final Extractor extractor : extractors) {
|
||||
context = extractor.extract(carrier);
|
||||
// Use incomplete TagContext only as last resort
|
||||
if (context != null && (context instanceof ExtractedContext)) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
public static Extractor createExtractor() {
|
||||
return new DatadogHttpCodec.Extractor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,26 +47,4 @@ public class HttpCodec {
|
|||
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
/** URL encode value */
|
||||
static 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;
|
||||
}
|
||||
|
||||
/** URL decode value */
|
||||
static 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
package datadog.opentracing.propagation;
|
||||
|
||||
import io.opentracing.SpanContext;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* When calling extract, we allow for grabbing other configured headers as tags. Those tags are
|
||||
* returned here even if the rest of the request would have returned null.
|
||||
*/
|
||||
public class TagContext implements SpanContext {
|
||||
private final String origin;
|
||||
private final Map<String, String> tags;
|
||||
|
||||
public TagContext(final String origin, final Map<String, String> tags) {
|
||||
this.origin = origin;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toTraceId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSpanId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, String>> baggageItems() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.opentracing
|
||||
|
||||
import datadog.opentracing.propagation.ExtractedContext
|
||||
import datadog.opentracing.propagation.TagContext
|
||||
import datadog.trace.api.Config
|
||||
import datadog.trace.api.DDTags
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
|
|
@ -9,7 +8,6 @@ import datadog.trace.util.test.DDSpecification
|
|||
import io.opentracing.Scope
|
||||
import io.opentracing.noop.NoopSpan
|
||||
|
||||
import static datadog.opentracing.DDSpanContext.ORIGIN_KEY
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
|
||||
class DDSpanBuilderTest extends DDSpecification {
|
||||
|
|
@ -155,7 +153,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
1 * mockedContext.getTraceId() >> spanId
|
||||
1 * mockedContext.getSpanId() >> spanId
|
||||
_ * mockedContext.getServiceName() >> "foo"
|
||||
1 * mockedContext.getBaggageItems() >> [:]
|
||||
1 * mockedContext.getTrace() >> new PendingTrace(tracer, 1G)
|
||||
|
||||
final String expectedName = "fakeName"
|
||||
|
|
@ -210,8 +207,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
def expectedChildServiceName = "fakeServiceName-child"
|
||||
def expectedChildResourceName = "fakeResourceName-child"
|
||||
def expectedChildType = "fakeType-child"
|
||||
def expectedBaggageItemKey = "fakeKey"
|
||||
def expectedBaggageItemValue = "fakeValue"
|
||||
|
||||
final DDSpan parent =
|
||||
tracer
|
||||
|
|
@ -221,8 +216,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
.withSpanType(expectedParentType)
|
||||
.start()
|
||||
|
||||
parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue)
|
||||
|
||||
// ServiceName and SpanType are always set by the parent if they are not present in the child
|
||||
DDSpan span =
|
||||
tracer
|
||||
|
|
@ -233,7 +226,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
|
||||
expect:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedParentServiceName
|
||||
span.context().getResourceName() == expectedName
|
||||
span.context().getSpanType() == null
|
||||
|
|
@ -251,7 +243,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
|
||||
then:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedChildServiceName
|
||||
span.context().getResourceName() == expectedChildResourceName
|
||||
span.context().getSpanType() == expectedChildType
|
||||
|
|
@ -267,8 +258,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
def expectedChildServiceName = "fakeServiceName-child"
|
||||
def expectedChildResourceName = "fakeResourceName-child"
|
||||
def expectedChildType = "fakeType-child"
|
||||
def expectedBaggageItemKey = "fakeKey"
|
||||
def expectedBaggageItemValue = "fakeValue"
|
||||
|
||||
final DDSpan parent =
|
||||
tracer
|
||||
|
|
@ -278,8 +267,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
.withSpanType(expectedParentType)
|
||||
.start()
|
||||
|
||||
parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue)
|
||||
|
||||
// ServiceName and SpanType are always set by the parent if they are not present in the child
|
||||
DDSpan span =
|
||||
tracer
|
||||
|
|
@ -288,14 +275,11 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
.addReference("child_of", parent.context())
|
||||
.start()
|
||||
|
||||
println span.getBaggageItem(expectedBaggageItemKey)
|
||||
println expectedBaggageItemValue
|
||||
println span.context().getSpanType()
|
||||
println expectedParentType
|
||||
|
||||
expect:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedParentServiceName
|
||||
span.context().getResourceName() == expectedName
|
||||
span.context().getSpanType() == null
|
||||
|
|
@ -313,7 +297,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
|
||||
then:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedChildServiceName
|
||||
span.context().getResourceName() == expectedChildResourceName
|
||||
span.context().getSpanType() == expectedChildType
|
||||
|
|
@ -329,8 +312,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
def expectedChildServiceName = "fakeServiceName-child"
|
||||
def expectedChildResourceName = "fakeResourceName-child"
|
||||
def expectedChildType = "fakeType-child"
|
||||
def expectedBaggageItemKey = "fakeKey"
|
||||
def expectedBaggageItemValue = "fakeValue"
|
||||
|
||||
final DDSpan parent =
|
||||
tracer
|
||||
|
|
@ -340,8 +321,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
.withSpanType(expectedParentType)
|
||||
.start()
|
||||
|
||||
parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue)
|
||||
|
||||
// ServiceName and SpanType are always set by the parent if they are not present in the child
|
||||
DDSpan span =
|
||||
tracer
|
||||
|
|
@ -350,14 +329,11 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
.addReference("follows_from", parent.context())
|
||||
.start()
|
||||
|
||||
println span.getBaggageItem(expectedBaggageItemKey)
|
||||
println expectedBaggageItemValue
|
||||
println span.context().getSpanType()
|
||||
println expectedParentType
|
||||
|
||||
expect:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedParentServiceName
|
||||
span.context().getResourceName() == expectedName
|
||||
span.context().getSpanType() == null
|
||||
|
|
@ -375,7 +351,6 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
|
||||
then:
|
||||
span.getOperationName() == expectedName
|
||||
span.getBaggageItem(expectedBaggageItemKey) == expectedBaggageItemValue
|
||||
span.context().getServiceName() == expectedChildServiceName
|
||||
span.context().getResourceName() == expectedChildResourceName
|
||||
span.context().getSpanType() == expectedChildType
|
||||
|
|
@ -413,43 +388,17 @@ class DDSpanBuilderTest extends DDSpecification {
|
|||
|
||||
def "ExtractedContext should populate new span details"() {
|
||||
setup:
|
||||
def thread = Thread.currentThread()
|
||||
final DDSpan span = tracer.buildSpan("op name")
|
||||
.asChildOf(extractedContext).start()
|
||||
|
||||
expect:
|
||||
span.traceId == extractedContext.traceId
|
||||
span.parentId == extractedContext.spanId
|
||||
span.context().origin == extractedContext.origin
|
||||
span.context().baggageItems == extractedContext.baggage
|
||||
span.context().@tags == extractedContext.tags + [(Config.RUNTIME_ID_TAG) : config.getRuntimeId(),
|
||||
(Config.LANGUAGE_TAG_KEY): Config.LANGUAGE_TAG_VALUE,
|
||||
(DDTags.THREAD_NAME) : thread.name, (DDTags.THREAD_ID): thread.id]
|
||||
|
||||
where:
|
||||
extractedContext | _
|
||||
new ExtractedContext(1G, 2G, null, [:], [:]) | _
|
||||
new ExtractedContext(3G, 4G, "some-origin", ["asdf": "qwer"], [(ORIGIN_KEY): "some-origin", "zxcv": "1234"]) | _
|
||||
}
|
||||
|
||||
def "TagContext should populate default span details"() {
|
||||
setup:
|
||||
def thread = Thread.currentThread()
|
||||
final DDSpan span = tracer.buildSpan("op name").asChildOf(tagContext).start()
|
||||
|
||||
expect:
|
||||
span.traceId != 0G
|
||||
span.parentId == 0G
|
||||
span.context().origin == tagContext.origin
|
||||
span.context().baggageItems == [:]
|
||||
span.context().@tags == tagContext.tags + [(Config.RUNTIME_ID_TAG) : config.getRuntimeId(),
|
||||
(Config.LANGUAGE_TAG_KEY): Config.LANGUAGE_TAG_VALUE,
|
||||
(DDTags.THREAD_NAME) : thread.name, (DDTags.THREAD_ID): thread.id]
|
||||
|
||||
where:
|
||||
tagContext | _
|
||||
new TagContext(null, [:]) | _
|
||||
new TagContext("some-origin", [(ORIGIN_KEY): "some-origin", "asdf": "qwer"]) | _
|
||||
extractedContext | _
|
||||
new ExtractedContext(1G, 2G) | _
|
||||
new ExtractedContext(3G, 4G) | _
|
||||
}
|
||||
|
||||
def "global span tags populated on each span"() {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ class DDSpanSerializationTest extends DDSpecification {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
Collections.emptyMap(),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package datadog.opentracing
|
||||
|
||||
|
||||
import datadog.opentracing.propagation.ExtractedContext
|
||||
import datadog.opentracing.propagation.TagContext
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.SpanContext
|
||||
|
|
@ -26,8 +24,6 @@ class DDSpanTest extends DDSpecification {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.<String, String> emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
|
|
@ -148,23 +144,6 @@ class DDSpanTest extends DDSpecification {
|
|||
span.durationNano == 1
|
||||
}
|
||||
|
||||
def "origin set only on root span"() {
|
||||
setup:
|
||||
def parent = tracer.buildSpan("testParent").asChildOf(extractedContext).start().context()
|
||||
def child = tracer.buildSpan("testChild1").asChildOf(parent).start().context()
|
||||
|
||||
expect:
|
||||
parent.origin == "some-origin"
|
||||
parent.@origin == "some-origin" // Access field directly instead of getter.
|
||||
child.origin == "some-origin"
|
||||
child.@origin == null // Access field directly instead of getter.
|
||||
|
||||
where:
|
||||
extractedContext | _
|
||||
new TagContext("some-origin", [:]) | _
|
||||
new ExtractedContext(1G, 2G, "some-origin", [:], [:]) | _
|
||||
}
|
||||
|
||||
def "isRootSpan() in and not in the context of distributed tracing"() {
|
||||
setup:
|
||||
def root = tracer.buildSpan("root").asChildOf((SpanContext) extractedContext).start()
|
||||
|
|
@ -179,9 +158,9 @@ class DDSpanTest extends DDSpecification {
|
|||
root.finish()
|
||||
|
||||
where:
|
||||
extractedContext | isTraceRootSpan
|
||||
null | true
|
||||
new ExtractedContext(123G, 456G, "789", [:], [:]) | false
|
||||
extractedContext | isTraceRootSpan
|
||||
null | true
|
||||
new ExtractedContext(123G, 456G) | false
|
||||
}
|
||||
|
||||
def "getApplicationRootSpan() in and not in the context of distributed tracing"() {
|
||||
|
|
@ -201,8 +180,8 @@ class DDSpanTest extends DDSpecification {
|
|||
root.finish()
|
||||
|
||||
where:
|
||||
extractedContext | isTraceRootSpan
|
||||
null | true
|
||||
new ExtractedContext(123G, 456G, "789", [:], [:]) | false
|
||||
extractedContext | isTraceRootSpan
|
||||
null | true
|
||||
new ExtractedContext(123G, 456G) | false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ class SpanFactory {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
Collections.emptyMap(),
|
||||
|
|
@ -36,8 +34,6 @@ class SpanFactory {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
Collections.emptyMap(),
|
||||
|
|
@ -54,8 +50,6 @@ class SpanFactory {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
Collections.emptyMap(),
|
||||
|
|
@ -74,8 +68,6 @@ class SpanFactory {
|
|||
serviceName,
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
Collections.emptyMap(),
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class SpanDecoratorTest extends DDSpecification {
|
|||
new LoggingWriter(),
|
||||
"some-runtime-id",
|
||||
emptyMap(),
|
||||
emptyMap(),
|
||||
emptyMap()
|
||||
)
|
||||
|
||||
|
|
@ -57,10 +56,10 @@ class SpanDecoratorTest extends DDSpecification {
|
|||
span.getServiceName() == expected
|
||||
|
||||
where:
|
||||
tag | name | expected
|
||||
DDTags.SERVICE_NAME | "some-service" | "some-service"
|
||||
"service" | "some-service" | "some-service"
|
||||
Tags.PEER_SERVICE.key | "some-service" | "some-service"
|
||||
tag | name | expected
|
||||
DDTags.SERVICE_NAME | "some-service" | "some-service"
|
||||
"service" | "some-service" | "some-service"
|
||||
Tags.PEER_SERVICE.key | "some-service" | "some-service"
|
||||
}
|
||||
|
||||
def "set service name from servlet.context with context '#context'"() {
|
||||
|
|
@ -90,7 +89,6 @@ class SpanDecoratorTest extends DDSpecification {
|
|||
new LoggingWriter(),
|
||||
"some-runtime-id",
|
||||
emptyMap(),
|
||||
emptyMap(),
|
||||
emptyMap()
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -112,8 +112,6 @@ class URLAsResourceNameTest extends DDSpecification {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
null,
|
||||
Collections.<String, String> emptyMap(),
|
||||
false,
|
||||
"fakeType",
|
||||
tags,
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.SpanContext
|
||||
import io.opentracing.propagation.TextMapExtractAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY
|
||||
|
||||
class B3HttpExtractorTest extends DDSpecification {
|
||||
|
||||
HttpCodec.Extractor extractor = new B3HttpCodec.Extractor(["SOME_HEADER": "some-tag"])
|
||||
|
||||
def "extract http headers"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()): traceId.toString(16).toLowerCase(),
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId.toString(16).toLowerCase(),
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context.traceId == traceId
|
||||
context.spanId == spanId
|
||||
context.baggage == [:]
|
||||
context.tags == ["some-tag": "my-interesting-info"]
|
||||
context.origin == null
|
||||
|
||||
where:
|
||||
traceId | spanId
|
||||
1G | 2G
|
||||
TRACE_ID_MAX | TRACE_ID_MAX - 1
|
||||
TRACE_ID_MAX - 1 | TRACE_ID_MAX
|
||||
}
|
||||
|
||||
def "extract 128 bit id truncates id to 64 bit"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()): traceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId,
|
||||
]
|
||||
|
||||
when:
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
if (expectedTraceId) {
|
||||
assert context.traceId == expectedTraceId
|
||||
assert context.spanId == expectedSpanId
|
||||
} else {
|
||||
assert context == null
|
||||
}
|
||||
|
||||
where:
|
||||
traceId | spanId | expectedTraceId | expectedSpanId
|
||||
"-1" | "1" | null | 0G
|
||||
"1" | "-1" | null | 0G
|
||||
"0" | "1" | null | 0G
|
||||
"00001" | "00001" | 1G | 1G
|
||||
"463ac35c9f6413ad" | "463ac35c9f6413ad" | 5060571933882717101G | 5060571933882717101G
|
||||
"463ac35c9f6413ad48485a3953bb6124" | "1" | 5208512171318403364G | 1G
|
||||
"f" * 16 | "1" | TRACE_ID_MAX | 1G
|
||||
"a" * 16 + "f" * 16 | "1" | TRACE_ID_MAX | 1G
|
||||
"1" + "f" * 32 | "1" | null | 1G
|
||||
"0" + "f" * 32 | "1" | null | 1G
|
||||
"1" | "f" * 16 | 1G | TRACE_ID_MAX
|
||||
"1" | "1" + "f" * 16 | null | 0G
|
||||
"1" | "000" + "f" * 16 | 1G | TRACE_ID_MAX
|
||||
}
|
||||
|
||||
def "extract header tags with no propagation"() {
|
||||
when:
|
||||
TagContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
!(context instanceof ExtractedContext)
|
||||
context.getTags() == ["some-tag": "my-interesting-info"]
|
||||
|
||||
where:
|
||||
headers | _
|
||||
[SOME_HEADER: "my-interesting-info"] | _
|
||||
}
|
||||
|
||||
def "extract empty headers returns null"() {
|
||||
expect:
|
||||
extractor.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
|
||||
}
|
||||
|
||||
def "extract http headers with invalid non-numeric ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()): "traceId",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "spanId",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context == null
|
||||
}
|
||||
|
||||
def "extract http headers with out of range span ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()): "0",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "-1",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
|
||||
when:
|
||||
SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context == null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.opentracing.DDSpanContext
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.PendingTrace
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY
|
||||
|
||||
class B3HttpInjectorTest extends DDSpecification {
|
||||
|
||||
HttpCodec.Injector injector = new B3HttpCodec.Injector()
|
||||
|
||||
def "inject http headers"() {
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
traceId,
|
||||
spanId,
|
||||
0G,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
"fakeOrigin",
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, 1G),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = Mock()
|
||||
|
||||
when:
|
||||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
then:
|
||||
1 * carrier.put(TRACE_ID_KEY, traceId.toString(16).toLowerCase())
|
||||
1 * carrier.put(SPAN_ID_KEY, spanId.toString(16).toLowerCase())
|
||||
0 * _
|
||||
|
||||
where:
|
||||
traceId | spanId
|
||||
1G | 2G
|
||||
TRACE_ID_MAX | TRACE_ID_MAX - 1
|
||||
TRACE_ID_MAX - 1 | TRACE_ID_MAX
|
||||
}
|
||||
}
|
||||
|
|
@ -5,62 +5,32 @@ import io.opentracing.SpanContext
|
|||
import io.opentracing.propagation.TextMapExtractAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
|
||||
|
||||
class DatadogHttpExtractorTest extends DDSpecification {
|
||||
|
||||
HttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"])
|
||||
HttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor()
|
||||
|
||||
def "extract http headers"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : traceId.toString(),
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId.toString(),
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
(TRACE_ID_KEY.toUpperCase()): traceId.toString(),
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId.toString()
|
||||
]
|
||||
|
||||
if (origin) {
|
||||
headers.put(ORIGIN_KEY, origin)
|
||||
}
|
||||
|
||||
when:
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context.traceId == new BigInteger(traceId)
|
||||
context.spanId == new BigInteger(spanId)
|
||||
context.baggage == ["k1": "v1", "k2": "v2"]
|
||||
context.tags == ["some-tag": "my-interesting-info"]
|
||||
context.origin == origin
|
||||
|
||||
where:
|
||||
traceId | spanId | origin
|
||||
"1" | "2" | null
|
||||
"2" | "3" | "saipan"
|
||||
TRACE_ID_MAX.toString() | (TRACE_ID_MAX - 1).toString() | "saipan"
|
||||
(TRACE_ID_MAX - 1).toString() | TRACE_ID_MAX.toString() | "saipan"
|
||||
}
|
||||
|
||||
def "extract header tags with no propagation"() {
|
||||
when:
|
||||
TagContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
!(context instanceof ExtractedContext)
|
||||
context.getTags() == ["some-tag": "my-interesting-info"]
|
||||
if (headers.containsKey(ORIGIN_KEY)) {
|
||||
assert ((TagContext) context).origin == "my-origin"
|
||||
}
|
||||
|
||||
where:
|
||||
headers | _
|
||||
[SOME_HEADER: "my-interesting-info"] | _
|
||||
[(ORIGIN_KEY): "my-origin", SOME_HEADER: "my-interesting-info"] | _
|
||||
traceId | spanId
|
||||
"1" | "2"
|
||||
TRACE_ID_MAX.toString() | (TRACE_ID_MAX - 1).toString()
|
||||
(TRACE_ID_MAX - 1).toString() | TRACE_ID_MAX.toString()
|
||||
}
|
||||
|
||||
def "extract empty headers returns null"() {
|
||||
|
|
@ -71,11 +41,8 @@ class DatadogHttpExtractorTest extends DDSpecification {
|
|||
def "extract http headers with invalid non-numeric ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : "traceId",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "spanId",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
(TRACE_ID_KEY.toUpperCase()): "traceId",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "spanId"
|
||||
]
|
||||
|
||||
when:
|
||||
|
|
@ -89,11 +56,8 @@ class DatadogHttpExtractorTest extends DDSpecification {
|
|||
setup:
|
||||
String outOfRangeTraceId = (TRACE_ID_MAX + 1).toString()
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : outOfRangeTraceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : "0",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
(TRACE_ID_KEY.toUpperCase()): outOfRangeTraceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : "0"
|
||||
]
|
||||
|
||||
when:
|
||||
|
|
@ -106,11 +70,8 @@ class DatadogHttpExtractorTest extends DDSpecification {
|
|||
def "extract http headers with out of range span ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : "0",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "-1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
(TRACE_ID_KEY.toUpperCase()): "0",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "-1"
|
||||
]
|
||||
|
||||
when:
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import datadog.trace.util.test.DDSpecification
|
|||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
|
||||
|
||||
|
|
@ -29,13 +27,6 @@ class DatadogHttpInjectorTest extends DDSpecification {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
origin,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
|
|
@ -50,18 +41,12 @@ class DatadogHttpInjectorTest extends DDSpecification {
|
|||
then:
|
||||
1 * carrier.put(TRACE_ID_KEY, traceId.toString())
|
||||
1 * carrier.put(SPAN_ID_KEY, spanId.toString())
|
||||
1 * carrier.put(OT_BAGGAGE_PREFIX + "k1", "v1")
|
||||
1 * carrier.put(OT_BAGGAGE_PREFIX + "k2", "v2")
|
||||
if (origin) {
|
||||
1 * carrier.put(ORIGIN_KEY, origin)
|
||||
}
|
||||
0 * _
|
||||
|
||||
where:
|
||||
traceId | spanId | origin
|
||||
1G | 2G | null
|
||||
1G | 2G | "saipan"
|
||||
TRACE_ID_MAX | TRACE_ID_MAX - 1 | "saipan"
|
||||
TRACE_ID_MAX - 1 | TRACE_ID_MAX | null
|
||||
traceId | spanId
|
||||
1G | 2G
|
||||
TRACE_ID_MAX | TRACE_ID_MAX - 1
|
||||
TRACE_ID_MAX - 1 | TRACE_ID_MAX
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,146 +0,0 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.SpanContext
|
||||
import io.opentracing.propagation.TextMapExtractAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX
|
||||
import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY
|
||||
import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY
|
||||
|
||||
class HaystackHttpExtractorTest extends DDSpecification {
|
||||
|
||||
HttpCodec.Extractor extractor = new HaystackHttpCodec.Extractor(["SOME_HEADER": "some-tag"])
|
||||
|
||||
def "extract http headers"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : traceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId,
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context.traceId == new BigInteger(traceId)
|
||||
context.spanId == new BigInteger(spanId)
|
||||
context.baggage == ["k1": "v1", "k2": "v2"]
|
||||
context.tags == ["some-tag": "my-interesting-info"]
|
||||
context.origin == origin
|
||||
|
||||
where:
|
||||
traceId | spanId | origin
|
||||
"1" | "2" | null
|
||||
TRACE_ID_MAX.toString() | (TRACE_ID_MAX - 1).toString() | null
|
||||
(TRACE_ID_MAX - 1).toString() | TRACE_ID_MAX.toString() | null
|
||||
}
|
||||
|
||||
def "extract header tags with no propagation"() {
|
||||
when:
|
||||
TagContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
!(context instanceof ExtractedContext)
|
||||
context.getTags() == ["some-tag": "my-interesting-info"]
|
||||
|
||||
|
||||
where:
|
||||
headers | _
|
||||
[SOME_HEADER: "my-interesting-info"] | _
|
||||
}
|
||||
|
||||
def "extract empty headers returns null"() {
|
||||
expect:
|
||||
extractor.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
|
||||
}
|
||||
|
||||
def "extract http headers with invalid non-numeric ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : "traceId",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "spanId",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context == null
|
||||
}
|
||||
|
||||
def "extract http headers with out of range trace ID"() {
|
||||
setup:
|
||||
String outOfRangeTraceId = (TRACE_ID_MAX + 1).toString()
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : outOfRangeTraceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : "0",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context == null
|
||||
}
|
||||
|
||||
def "extract http headers with out of range span ID"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()) : "0",
|
||||
(SPAN_ID_KEY.toUpperCase()) : "-1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
|
||||
(OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
|
||||
SOME_HEADER : "my-interesting-info",
|
||||
]
|
||||
|
||||
when:
|
||||
SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
context == null
|
||||
}
|
||||
|
||||
def "more ID range validation"() {
|
||||
setup:
|
||||
def headers = [
|
||||
(TRACE_ID_KEY.toUpperCase()): traceId,
|
||||
(SPAN_ID_KEY.toUpperCase()) : spanId,
|
||||
]
|
||||
|
||||
when:
|
||||
final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
|
||||
|
||||
then:
|
||||
if (expectedTraceId) {
|
||||
assert context.traceId == expectedTraceId
|
||||
assert context.spanId == expectedSpanId
|
||||
} else {
|
||||
assert context == null
|
||||
}
|
||||
|
||||
where:
|
||||
gtTraceId | gSpanId | expectedTraceId | expectedSpanId
|
||||
"-1" | "1" | null | 0G
|
||||
"1" | "-1" | null | 0G
|
||||
"0" | "1" | null | 0G
|
||||
"1" | "0" | 1G | 0G
|
||||
"$TRACE_ID_MAX" | "1" | TRACE_ID_MAX | 1G
|
||||
"${TRACE_ID_MAX + 1}" | "1" | null | 1G
|
||||
"1" | "$TRACE_ID_MAX" | 1G | TRACE_ID_MAX
|
||||
"1" | "${TRACE_ID_MAX + 1}" | null | 0G
|
||||
|
||||
traceId = gtTraceId.toString()
|
||||
spanId = gSpanId.toString()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.opentracing.DDSpanContext
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.PendingTrace
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.opentracing.propagation.HaystackHttpCodec.*
|
||||
|
||||
class HaystackHttpInjectorTest extends DDSpecification {
|
||||
|
||||
HttpCodec.Injector injector = new HaystackHttpCodec.Injector()
|
||||
|
||||
def "inject http headers"() {
|
||||
setup:
|
||||
def writer = new ListWriter()
|
||||
def tracer = new DDTracer(writer)
|
||||
final DDSpanContext mockedContext =
|
||||
new DDSpanContext(
|
||||
traceId,
|
||||
spanId,
|
||||
0G,
|
||||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
origin,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
new PendingTrace(tracer, 1G),
|
||||
tracer)
|
||||
|
||||
final Map<String, String> carrier = Mock()
|
||||
|
||||
when:
|
||||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
then:
|
||||
1 * carrier.put(TRACE_ID_KEY, traceId.toString())
|
||||
1 * carrier.put(SPAN_ID_KEY, spanId.toString())
|
||||
1 * carrier.put(OT_BAGGAGE_PREFIX + "k1", "v1")
|
||||
1 * carrier.put(OT_BAGGAGE_PREFIX + "k2", "v2")
|
||||
|
||||
|
||||
where:
|
||||
traceId | spanId | origin
|
||||
1G | 2G | null
|
||||
TRACE_ID_MAX | TRACE_ID_MAX - 1 | null
|
||||
TRACE_ID_MAX - 1 | TRACE_ID_MAX | null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,12 @@
|
|||
package datadog.opentracing.propagation
|
||||
|
||||
import datadog.trace.api.Config
|
||||
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.SpanContext
|
||||
import io.opentracing.propagation.TextMapExtractAdapter
|
||||
import spock.lang.Shared
|
||||
|
||||
import static datadog.opentracing.DDTracer.TRACE_ID_MAX
|
||||
import static datadog.trace.api.Config.PropagationStyle.B3
|
||||
import static datadog.trace.api.Config.PropagationStyle.DATADOG
|
||||
|
||||
class HttpExtractorTest extends DDSpecification {
|
||||
|
||||
|
|
@ -17,10 +15,7 @@ class HttpExtractorTest extends DDSpecification {
|
|||
|
||||
def "extract http headers"() {
|
||||
setup:
|
||||
Config config = Mock(Config) {
|
||||
getPropagationStylesToExtract() >> styles
|
||||
}
|
||||
HttpCodec.Extractor extractor = HttpCodec.createExtractor(config, ["SOME_HEADER": "some-tag"])
|
||||
HttpCodec.Extractor extractor = HttpCodec.createExtractor()
|
||||
|
||||
final Map<String, String> actual = [:]
|
||||
if (datadogTraceId != null) {
|
||||
|
|
@ -29,53 +24,24 @@ class HttpExtractorTest extends DDSpecification {
|
|||
if (datadogSpanId != null) {
|
||||
actual.put(DatadogHttpCodec.SPAN_ID_KEY.toUpperCase(), datadogSpanId)
|
||||
}
|
||||
if (b3TraceId != null) {
|
||||
actual.put(B3HttpCodec.TRACE_ID_KEY.toUpperCase(), b3TraceId)
|
||||
}
|
||||
if (b3SpanId != null) {
|
||||
actual.put(B3HttpCodec.SPAN_ID_KEY.toUpperCase(), b3SpanId)
|
||||
}
|
||||
|
||||
if (putDatadogFields) {
|
||||
actual.put("SOME_HEADER", "my-interesting-info")
|
||||
}
|
||||
|
||||
when:
|
||||
final SpanContext context = extractor.extract(new TextMapExtractAdapter(actual))
|
||||
|
||||
then:
|
||||
if (tagContext) {
|
||||
assert context instanceof TagContext
|
||||
if (expectedTraceId == null) {
|
||||
assert context == null
|
||||
} else {
|
||||
if (expectedTraceId == null) {
|
||||
assert context == null
|
||||
} else {
|
||||
assert context.traceId == expectedTraceId
|
||||
assert context.spanId == expectedSpanId
|
||||
}
|
||||
}
|
||||
|
||||
if (expectDatadogFields) {
|
||||
assert context.tags == ["some-tag": "my-interesting-info"]
|
||||
assert context.traceId == expectedTraceId
|
||||
assert context.spanId == expectedSpanId
|
||||
}
|
||||
|
||||
where:
|
||||
styles | datadogTraceId | datadogSpanId | b3TraceId | b3SpanId | expectedTraceId | expectedSpanId | putDatadogFields | expectDatadogFields | tagContext
|
||||
[DATADOG, B3] | "1" | "2" | "a" | "b" | 1G | 2G | true | true | false
|
||||
[DATADOG, B3] | null | null | "a" | "b" | 10G | 11G | false | false | true
|
||||
[DATADOG, B3] | null | null | "a" | "b" | null | null | true | true | true
|
||||
[DATADOG] | "1" | "2" | "a" | "b" | 1G | 2G | true | true | false
|
||||
[B3] | "1" | "2" | "a" | "b" | 10G | 11G | false | false | false
|
||||
[B3, DATADOG] | "1" | "2" | "a" | "b" | 10G | 11G | false | false | false
|
||||
[] | "1" | "2" | "a" | "b" | null | null | false | false | false
|
||||
[DATADOG, B3] | "abc" | "2" | "a" | "b" | 10G | 11G | false | false | false
|
||||
[DATADOG] | "abc" | "2" | "a" | "b" | null | null | false | false | false
|
||||
[DATADOG, B3] | outOfRangeTraceId | "2" | "a" | "b" | 10G | 11G | false | false | false
|
||||
[DATADOG, B3] | "1" | outOfRangeTraceId | "a" | "b" | 10G | 11G | false | false | false
|
||||
[DATADOG] | outOfRangeTraceId | "2" | "a" | "b" | null | null | false | false | false
|
||||
[DATADOG] | "1" | outOfRangeTraceId | "a" | "b" | null | null | false | false | false
|
||||
[DATADOG, B3] | "1" | "2" | outOfRangeTraceId | "b" | 1G | 2G | true | false | false
|
||||
[DATADOG, B3] | "1" | "2" | "a" | outOfRangeTraceId | 1G | 2G | true | false | false
|
||||
datadogTraceId | datadogSpanId | expectedTraceId | expectedSpanId
|
||||
"1" | "2" | 1G | 2G
|
||||
"abc" | "2" | null | null
|
||||
outOfRangeTraceId | "2" | null | null
|
||||
"1" | outOfRangeTraceId | null | null
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,14 @@ package datadog.opentracing.propagation
|
|||
import datadog.opentracing.DDSpanContext
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.PendingTrace
|
||||
import datadog.trace.api.Config
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
import datadog.trace.util.test.DDSpecification
|
||||
import io.opentracing.propagation.TextMapInjectAdapter
|
||||
|
||||
import static datadog.trace.api.Config.PropagationStyle.B3
|
||||
import static datadog.trace.api.Config.PropagationStyle.DATADOG
|
||||
|
||||
class HttpInjectorTest extends DDSpecification {
|
||||
|
||||
def "inject http headers"() {
|
||||
setup:
|
||||
Config config = Mock(Config) {
|
||||
getPropagationStylesToInject() >> styles
|
||||
}
|
||||
HttpCodec.Injector injector = HttpCodec.createInjector(config)
|
||||
HttpCodec.Injector injector = HttpCodec.createInjector()
|
||||
|
||||
def traceId = 1G
|
||||
def spanId = 2G
|
||||
|
|
@ -33,13 +25,6 @@ class HttpInjectorTest extends DDSpecification {
|
|||
"fakeService",
|
||||
"fakeOperation",
|
||||
"fakeResource",
|
||||
origin,
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
put("k1", "v1")
|
||||
put("k2", "v2")
|
||||
}
|
||||
},
|
||||
false,
|
||||
"fakeType",
|
||||
null,
|
||||
|
|
@ -52,29 +37,8 @@ class HttpInjectorTest extends DDSpecification {
|
|||
injector.inject(mockedContext, new TextMapInjectAdapter(carrier))
|
||||
|
||||
then:
|
||||
if (styles.contains(DATADOG)) {
|
||||
1 * carrier.put(DatadogHttpCodec.TRACE_ID_KEY, traceId.toString())
|
||||
1 * carrier.put(DatadogHttpCodec.SPAN_ID_KEY, spanId.toString())
|
||||
1 * carrier.put(DatadogHttpCodec.OT_BAGGAGE_PREFIX + "k1", "v1")
|
||||
1 * carrier.put(DatadogHttpCodec.OT_BAGGAGE_PREFIX + "k2", "v2")
|
||||
if (origin) {
|
||||
1 * carrier.put(DatadogHttpCodec.ORIGIN_KEY, origin)
|
||||
}
|
||||
}
|
||||
if (styles.contains(B3)) {
|
||||
1 * carrier.put(B3HttpCodec.TRACE_ID_KEY, traceId.toString())
|
||||
1 * carrier.put(B3HttpCodec.SPAN_ID_KEY, spanId.toString())
|
||||
}
|
||||
1 * carrier.put(DatadogHttpCodec.TRACE_ID_KEY, traceId.toString())
|
||||
1 * carrier.put(DatadogHttpCodec.SPAN_ID_KEY, spanId.toString())
|
||||
0 * _
|
||||
|
||||
where:
|
||||
styles | origin
|
||||
[DATADOG, B3] | null
|
||||
[DATADOG, B3] | "saipan"
|
||||
[DATADOG] | null
|
||||
[DATADOG] | "saipan"
|
||||
[B3] | null
|
||||
[B3] | "saipan"
|
||||
[B3, DATADOG] | "saipan"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace
|
||||
|
||||
import datadog.opentracing.DDTracer
|
||||
import datadog.opentracing.propagation.HttpCodec
|
||||
import datadog.opentracing.propagation.DatadogHttpCodec
|
||||
import datadog.trace.api.Config
|
||||
import datadog.trace.common.writer.DDAgentWriter
|
||||
import datadog.trace.common.writer.ListWriter
|
||||
|
|
@ -12,7 +12,6 @@ import org.junit.contrib.java.lang.system.EnvironmentVariables
|
|||
import org.junit.contrib.java.lang.system.RestoreSystemProperties
|
||||
|
||||
import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
|
||||
import static datadog.trace.api.Config.HEADER_TAGS
|
||||
import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED
|
||||
import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT
|
||||
import static datadog.trace.api.Config.PREFIX
|
||||
|
|
@ -47,8 +46,8 @@ class DDTracerTest extends DDSpecification {
|
|||
|
||||
tracer.spanContextDecorators.size() == 12
|
||||
|
||||
tracer.injector instanceof HttpCodec.CompoundInjector
|
||||
tracer.extractor instanceof HttpCodec.CompoundExtractor
|
||||
tracer.injector instanceof DatadogHttpCodec.Injector
|
||||
tracer.extractor instanceof DatadogHttpCodec.Extractor
|
||||
}
|
||||
|
||||
def "verify enabling health monitor"() {
|
||||
|
|
@ -79,17 +78,13 @@ class DDTracerTest extends DDSpecification {
|
|||
def "verify mapping configs on tracer"() {
|
||||
setup:
|
||||
System.setProperty(PREFIX + SPAN_TAGS, mapString)
|
||||
System.setProperty(PREFIX + HEADER_TAGS, mapString)
|
||||
|
||||
when:
|
||||
def config = new Config()
|
||||
def tracer = new DDTracer(config)
|
||||
// Datadog extractor gets placed first
|
||||
def taggedHeaders = tracer.extractor.extractors[0].taggedHeaders
|
||||
|
||||
then:
|
||||
tracer.defaultSpanTags == map
|
||||
taggedHeaders == map
|
||||
|
||||
where:
|
||||
mapString | map
|
||||
|
|
@ -131,7 +126,7 @@ class DDTracerTest extends DDSpecification {
|
|||
|
||||
def "root tags are applied only to root spans"() {
|
||||
setup:
|
||||
def tracer = new DDTracer('my_service', new ListWriter(), '', ['only_root': 'value'], [:], [:])
|
||||
def tracer = new DDTracer('my_service', new ListWriter(), '', ['only_root': 'value'], [:])
|
||||
def root = tracer.buildSpan('my_root').start()
|
||||
def child = tracer.buildSpan('my_child').asChildOf(root).start()
|
||||
|
||||
|
|
|
|||
|
|
@ -166,8 +166,6 @@ class DDAgentWriterTest extends DDSpecification {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"",
|
||||
Collections.emptyMap(),
|
||||
|
|
@ -203,8 +201,6 @@ class DDAgentWriterTest extends DDSpecification {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
"",
|
||||
Collections.emptyMap(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue