From 0f3da325b056853749b93eab4cc138e78d46fec1 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Mon, 27 Jan 2025 14:18:17 +0100 Subject: [PATCH 1/4] feat(core): Remove core propagation injection API --- .../java/datadog/trace/core/CoreTracer.java | 9 +- .../core/propagation/CorePropagation.java | 61 +-- .../datadog/trace/core/CoreTracerTest.groovy | 5 - .../propagation/CorePropagationTest.groovy | 389 +++++++++--------- .../instrumentation/api/AgentPropagation.java | 15 +- .../instrumentation/api/AgentTracer.java | 17 - 6 files changed, 199 insertions(+), 297 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 1c21645e5d2..3f5c5264a72 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -32,7 +32,6 @@ import datadog.trace.api.InstrumenterConfig; import datadog.trace.api.StatsDClient; import datadog.trace.api.TraceConfig; -import datadog.trace.api.TracePropagationStyle; import datadog.trace.api.config.GeneralConfig; import datadog.trace.api.experimental.DataStreamsCheckpointer; import datadog.trace.api.flare.TracerFlare; @@ -79,7 +78,6 @@ import datadog.trace.common.writer.WriterFactory; import datadog.trace.common.writer.ddintake.DDIntakeTraceInterceptor; import datadog.trace.context.TraceScope; -import datadog.trace.core.datastreams.DataStreamContextInjector; import datadog.trace.core.datastreams.DataStreamsMonitoring; import datadog.trace.core.datastreams.DefaultDataStreamsMonitoring; import datadog.trace.core.flare.TracerFlarePoller; @@ -719,13 +717,8 @@ private CoreTracer( HttpCodec.Extractor builtExtractor = extractor == null ? HttpCodec.createExtractor(config, this::captureTraceConfig) : extractor; builtExtractor = this.dataStreamsMonitoring.extractor(builtExtractor); - // Create all HTTP injectors plus the DSM one - Map injectors = - HttpCodec.allInjectorsFor(config, invertMap(baggageMapping)); - DataStreamContextInjector dataStreamContextInjector = this.dataStreamsMonitoring.injector(); // Store all propagators to propagation - this.propagation = - new CorePropagation(builtExtractor, injector, injectors, dataStreamContextInjector); + this.propagation = new CorePropagation(builtExtractor, this.dataStreamsMonitoring.injector()); // Check if standalone AppSec is enabled: // If enabled, use the standalone AppSec propagator by default that will limit tracing concern diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java index 75c3abb949c..d2379bb7e2c 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java @@ -1,18 +1,11 @@ package datadog.trace.core.propagation; -import datadog.trace.api.Config; -import datadog.trace.api.TracePropagationStyle; import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; -import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext; -import datadog.trace.core.DDSpanContext; import datadog.trace.core.datastreams.DataStreamContextInjector; import java.util.LinkedHashMap; -import java.util.Map; public class CorePropagation implements AgentPropagation { - private final HttpCodec.Injector injector; - private final Map injectors; private final DataStreamContextInjector dataStreamContextInjector; private final HttpCodec.Extractor extractor; @@ -20,62 +13,15 @@ public class CorePropagation implements AgentPropagation { * Constructor * * @param extractor The context extractor. - * @param defaultInjector The default injector when no {@link TracePropagationStyle} given. - * @param injectors All the other injectors available for context injection. * @param dataStreamContextInjector The DSM context injector, as a specific object until generic * context injection is available. */ public CorePropagation( - HttpCodec.Extractor extractor, - HttpCodec.Injector defaultInjector, - Map injectors, - DataStreamContextInjector dataStreamContextInjector) { + HttpCodec.Extractor extractor, DataStreamContextInjector dataStreamContextInjector) { this.extractor = extractor; - this.injector = defaultInjector; - this.injectors = injectors; this.dataStreamContextInjector = dataStreamContextInjector; } - @Override - public void inject(final AgentSpan span, final C carrier, final Setter setter) { - inject(span.context(), carrier, setter, null); - } - - @Override - public void inject(AgentSpanContext context, C carrier, Setter setter) { - inject(context, carrier, setter, null); - } - - @Override - public void inject(AgentSpan span, C carrier, Setter setter, TracePropagationStyle style) { - inject(span.context(), carrier, setter, style); - } - - private void inject( - AgentSpanContext context, C carrier, Setter setter, TracePropagationStyle style) { - if (!(context instanceof DDSpanContext)) { - return; - } - - final DDSpanContext ddSpanContext = (DDSpanContext) context; - ddSpanContext.getTraceCollector().setSamplingPriorityIfNecessary(); - - /** - * If the experimental appsec standalone feature is enabled and appsec propagation is disabled - * (no ASM events), stop propagation - */ - if (Config.get().isAppSecStandaloneEnabled() - && !ddSpanContext.getPropagationTags().isAppsecPropagationEnabled()) { - return; - } - - if (null == style) { - injector.inject(ddSpanContext, carrier, setter); - } else { - injectors.get(style).inject(ddSpanContext, carrier, setter); - } - } - @Override public void injectPathwayContext( AgentSpan span, C carrier, Setter setter, LinkedHashMap sortedTags) { @@ -100,9 +46,4 @@ public void injectPathwayContextWithoutSendingStats( this.dataStreamContextInjector.injectPathwayContextWithoutSendingStats( span, carrier, setter, sortedTags); } - - @Override - public AgentSpanContext.Extracted extract(final C carrier, final ContextVisitor getter) { - return extractor.extract(carrier, getter); - } } diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/CoreTracerTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/CoreTracerTest.groovy index 5d7dc2b915f..ba781cf010c 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/CoreTracerTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/CoreTracerTest.groovy @@ -19,8 +19,6 @@ import datadog.trace.common.sampling.Sampler import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.LoggingWriter -import datadog.trace.core.datastreams.DataStreamContextExtractor -import datadog.trace.core.propagation.HttpCodec import datadog.trace.core.tagprocessor.TagsPostProcessorFactory import datadog.trace.core.test.DDCoreSpecification import okhttp3.HttpUrl @@ -55,9 +53,6 @@ class CoreTracerTest extends DDCoreSpecification { tracer.writer instanceof DDAgentWriter tracer.statsDClient != null && tracer.statsDClient != StatsDClient.NO_OP - tracer.propagate().injector instanceof HttpCodec.CompoundInjector - tracer.propagate().extractor instanceof DataStreamContextExtractor - cleanup: tracer.close() } diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy index aa8bde29e1b..ec170a2bc6d 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy @@ -1,115 +1,106 @@ package datadog.trace.core.propagation -import datadog.trace.api.TracePropagationStyle -import datadog.trace.api.sampling.PrioritySampling import datadog.trace.bootstrap.instrumentation.api.AgentPropagation -import datadog.trace.common.writer.LoggingWriter -import datadog.trace.core.ControllableSampler import datadog.trace.core.datastreams.DataStreamContextInjector import datadog.trace.core.test.DDCoreSpecification -import static datadog.trace.api.TracePropagationStyle.B3MULTI -import static datadog.trace.api.TracePropagationStyle.DATADOG -import static datadog.trace.api.TracePropagationStyle.TRACECONTEXT -import static datadog.trace.api.sampling.PrioritySampling.SAMPLER_KEEP - class CorePropagationTest extends DDCoreSpecification { HttpCodec.Extractor extractor - HttpCodec.Injector datadogInjector - HttpCodec.Injector b3Injector - HttpCodec.Injector traceContextInjector - Map allInjectors + // HttpCodec.Injector datadogInjector + // HttpCodec.Injector b3Injector + // HttpCodec.Injector traceContextInjector + // Map allInjectors DataStreamContextInjector dataStreamContextInjector AgentPropagation propagation def setup() { extractor = Mock(HttpCodec.Extractor) - datadogInjector = Mock(HttpCodec.Injector) - b3Injector = Mock(HttpCodec.Injector) - traceContextInjector = Mock(HttpCodec.Injector) - allInjectors = [ - (DATADOG) : datadogInjector, - (B3MULTI) : b3Injector, - (TRACECONTEXT): traceContextInjector, - ] + // datadogInjector = Mock(HttpCodec.Injector) + // b3Injector = Mock(HttpCodec.Injector) + // traceContextInjector = Mock(HttpCodec.Injector) + // allInjectors = [ + // (DATADOG) : datadogInjector, + // (B3MULTI) : b3Injector, + // (TRACECONTEXT): traceContextInjector, + // ] dataStreamContextInjector = Mock(DataStreamContextInjector) - propagation = new CorePropagation(extractor, datadogInjector, allInjectors, dataStreamContextInjector) - } - - def 'test default injector for span'() { - setup: - def tracer = tracerBuilder().build() - def span = tracer.buildSpan('test', 'operation').start() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - propagation.inject(span, carrier, setter) - - then: - 1 * datadogInjector.inject(_, carrier, setter) - 0 * b3Injector.inject(_, carrier, setter) - 0 * traceContextInjector.inject(_, carrier, setter) - 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - - cleanup: - span.finish() - tracer.close() - } - - def 'test default injector for span context'() { - setup: - def tracer = tracerBuilder().build() - def span = tracer.buildSpan("test", "operation").start() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - def spanContext = span.context() - propagation.inject(spanContext, carrier, setter) - - then: - 1 * datadogInjector.inject(_, carrier, setter) - 0 * b3Injector.inject(_, carrier, setter) - 0 * traceContextInjector.inject(_, carrier, setter) - 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - - cleanup: - span.finish() - tracer.close() + propagation = new CorePropagation(extractor, dataStreamContextInjector) } - def 'test injector style selection'() { - setup: - def injector = allInjectors.get(style, datadogInjector) - def tracer = tracerBuilder().build() - def span = tracer.buildSpan('test', 'operation').start() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - propagation.inject(span, carrier, setter, style) - - then: - 1 * injector.inject(_, carrier, setter) - if (injector != datadogInjector) { - 0 * datadogInjector.inject(_, carrier, setter) - } - if (injector != b3Injector) { - 0 * b3Injector.inject(_, carrier, setter) - } - if (injector != traceContextInjector) { - 0 * traceContextInjector.inject(_, carrier, setter) - } - 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - - cleanup: - span.finish() - tracer.close() - - where: - style << [DATADOG, B3MULTI, TRACECONTEXT, null] - } + // def 'test default injector for span'() { + // setup: + // def tracer = tracerBuilder().build() + // def span = tracer.buildSpan('test', 'operation').start() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // propagation.inject(span, carrier, setter) + // + // then: + // 1 * datadogInjector.inject(_, carrier, setter) + // 0 * b3Injector.inject(_, carrier, setter) + // 0 * traceContextInjector.inject(_, carrier, setter) + // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) + // + // cleanup: + // span.finish() + // tracer.close() + // } + // + // def 'test default injector for span context'() { + // setup: + // def tracer = tracerBuilder().build() + // def span = tracer.buildSpan("test", "operation").start() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // def spanContext = span.context() + // propagation.inject(spanContext, carrier, setter) + // + // then: + // 1 * datadogInjector.inject(_, carrier, setter) + // 0 * b3Injector.inject(_, carrier, setter) + // 0 * traceContextInjector.inject(_, carrier, setter) + // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) + // + // cleanup: + // span.finish() + // tracer.close() + // } + // + // def 'test injector style selection'() { + // setup: + // def injector = allInjectors.get(style, datadogInjector) + // def tracer = tracerBuilder().build() + // def span = tracer.buildSpan('test', 'operation').start() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // propagation.inject(span, carrier, setter, style) + // + // then: + // 1 * injector.inject(_, carrier, setter) + // if (injector != datadogInjector) { + // 0 * datadogInjector.inject(_, carrier, setter) + // } + // if (injector != b3Injector) { + // 0 * b3Injector.inject(_, carrier, setter) + // } + // if (injector != traceContextInjector) { + // 0 * traceContextInjector.inject(_, carrier, setter) + // } + // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) + // + // cleanup: + // span.finish() + // tracer.close() + // + // where: + // style << [DATADOG, B3MULTI, TRACECONTEXT, null] + // } def 'test context extractor'() { setup: @@ -123,107 +114,107 @@ class CorePropagationTest extends DDCoreSpecification { 1 * extractor.extract(carrier, getter) } - def 'span priority set when injecting'() { - given: - injectSysConfig('writer.type', 'LoggingWriter') - def tracer = tracerBuilder().build() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - def root = tracer.buildSpan('test', 'operation').start() - def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - tracer.propagate().inject(child, carrier, setter) - - then: - root.getSamplingPriority() == SAMPLER_KEEP as int - child.getSamplingPriority() == root.getSamplingPriority() - 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - - cleanup: - child.finish() - root.finish() - tracer.close() - } - - def 'span priority only set after first injection'() { - given: - def sampler = new ControllableSampler() - def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - def root = tracer.buildSpan('test', 'operation').start() - def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - tracer.propagate().inject(child, carrier, setter) - - then: - root.getSamplingPriority() == SAMPLER_KEEP as int - child.getSamplingPriority() == root.getSamplingPriority() - 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - - when: - sampler.nextSamplingPriority = PrioritySampling.SAMPLER_DROP as int - def child2 = tracer.buildSpan('test', 'my_child2').asChildOf(root).start() - tracer.propagate().inject(child2, carrier, setter) - - then: - root.getSamplingPriority() == SAMPLER_KEEP as int - child.getSamplingPriority() == root.getSamplingPriority() - child2.getSamplingPriority() == root.getSamplingPriority() - 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - - cleanup: - child.finish() - child2.finish() - root.finish() - tracer.close() - } - - def "injection doesn't override set priority"() { - given: - def sampler = new ControllableSampler() - def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - def root = tracer.buildSpan('test', 'operation').start() - def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - child.setSamplingPriority(PrioritySampling.USER_DROP) - tracer.propagate().inject(child, carrier, setter) - - then: - root.getSamplingPriority() == PrioritySampling.USER_DROP as int - child.getSamplingPriority() == root.getSamplingPriority() - 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(PrioritySampling.USER_DROP)) - - cleanup: - child.finish() - root.finish() - tracer.close() - } - - def 'test ASM standalone billing stop propagation'() { - setup: - injectSysConfig("experimental.appsec.standalone.enabled", "true") - def tracer = tracerBuilder().build() - def span = tracer.buildSpan('test', 'operation').start() - def setter = Mock(AgentPropagation.Setter) - def carrier = new Object() - - when: - propagation.inject(span, carrier, setter) - - then: - 0 * datadogInjector.inject(_, carrier, setter) - 0 * b3Injector.inject(_, carrier, setter) - 0 * traceContextInjector.inject(_, carrier, setter) - 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - - cleanup: - span.finish() - tracer.close() - } + // def 'span priority set when injecting'() { + // given: + // injectSysConfig('writer.type', 'LoggingWriter') + // def tracer = tracerBuilder().build() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // def root = tracer.buildSpan('test', 'operation').start() + // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() + // tracer.propagate().inject(child, carrier, setter) + // + // then: + // root.getSamplingPriority() == SAMPLER_KEEP as int + // child.getSamplingPriority() == root.getSamplingPriority() + // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) + // + // cleanup: + // child.finish() + // root.finish() + // tracer.close() + // } + // + // def 'span priority only set after first injection'() { + // given: + // def sampler = new ControllableSampler() + // def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // def root = tracer.buildSpan('test', 'operation').start() + // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() + // tracer.propagate().inject(child, carrier, setter) + // + // then: + // root.getSamplingPriority() == SAMPLER_KEEP as int + // child.getSamplingPriority() == root.getSamplingPriority() + // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) + // + // when: + // sampler.nextSamplingPriority = PrioritySampling.SAMPLER_DROP as int + // def child2 = tracer.buildSpan('test', 'my_child2').asChildOf(root).start() + // tracer.propagate().inject(child2, carrier, setter) + // + // then: + // root.getSamplingPriority() == SAMPLER_KEEP as int + // child.getSamplingPriority() == root.getSamplingPriority() + // child2.getSamplingPriority() == root.getSamplingPriority() + // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) + // + // cleanup: + // child.finish() + // child2.finish() + // root.finish() + // tracer.close() + // } + // + // def "injection doesn't override set priority"() { + // given: + // def sampler = new ControllableSampler() + // def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // def root = tracer.buildSpan('test', 'operation').start() + // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() + // child.setSamplingPriority(PrioritySampling.USER_DROP) + // tracer.propagate().inject(child, carrier, setter) + // + // then: + // root.getSamplingPriority() == PrioritySampling.USER_DROP as int + // child.getSamplingPriority() == root.getSamplingPriority() + // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(PrioritySampling.USER_DROP)) + // + // cleanup: + // child.finish() + // root.finish() + // tracer.close() + // } + // + // def 'test ASM standalone billing stop propagation'() { + // setup: + // injectSysConfig("experimental.appsec.standalone.enabled", "true") + // def tracer = tracerBuilder().build() + // def span = tracer.buildSpan('test', 'operation').start() + // def setter = Mock(AgentPropagation.Setter) + // def carrier = new Object() + // + // when: + // propagation.inject(span, carrier, setter) + // + // then: + // 0 * datadogInjector.inject(_, carrier, setter) + // 0 * b3Injector.inject(_, carrier, setter) + // 0 * traceContextInjector.inject(_, carrier, setter) + // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) + // + // cleanup: + // span.finish() + // tracer.close() + // } } diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java index 1ed21c3840f..d0333e2d906 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java @@ -2,10 +2,11 @@ import static datadog.context.propagation.Concern.named; +import datadog.context.Context; import datadog.context.propagation.CarrierSetter; import datadog.context.propagation.CarrierVisitor; import datadog.context.propagation.Concern; -import datadog.trace.api.TracePropagationStyle; +import datadog.context.propagation.Propagators; import java.util.LinkedHashMap; import java.util.function.BiConsumer; import javax.annotation.ParametersAreNonnullByDefault; @@ -15,12 +16,6 @@ public interface AgentPropagation { Concern XRAY_TRACING_CONCERN = named("tracing-xray"); Concern STANDALONE_ASM_CONCERN = named("asm-standalone"); - void inject(AgentSpan span, C carrier, Setter setter); - - void inject(AgentSpanContext context, C carrier, Setter setter); - - void inject(AgentSpan span, C carrier, Setter setter, TracePropagationStyle style); - // The input tags should be sorted. void injectPathwayContext( AgentSpan span, C carrier, Setter setter, LinkedHashMap sortedTags); @@ -40,7 +35,11 @@ interface Setter extends CarrierSetter { void set(C carrier, String key, String value); } - AgentSpanContext.Extracted extract(C carrier, ContextVisitor getter); + default AgentSpanContext.Extracted extract(final C carrier, final ContextVisitor getter) { + Context extracted = Propagators.defaultPropagator().extract(Context.root(), carrier, getter); + AgentSpan extractedSpan = AgentSpan.fromContext(extracted); + return extractedSpan == null ? null : (AgentSpanContext.Extracted) extractedSpan.context(); + } interface KeyClassifier { boolean accept(String key, String value); diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java index ac5e54d8f7a..c7a5f76a9e5 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java @@ -7,7 +7,6 @@ import datadog.trace.api.EndpointCheckpointer; import datadog.trace.api.EndpointTracker; import datadog.trace.api.TraceConfig; -import datadog.trace.api.TracePropagationStyle; import datadog.trace.api.experimental.DataStreamsCheckpointer; import datadog.trace.api.experimental.DataStreamsContextCarrier; import datadog.trace.api.gateway.CallbackProvider; @@ -585,17 +584,6 @@ public void updatePreferredServiceName(String serviceName) { static class NoopAgentPropagation implements AgentPropagation { static final NoopAgentPropagation INSTANCE = new NoopAgentPropagation(); - @Override - public void inject(final AgentSpan span, final C carrier, final Setter setter) {} - - @Override - public void inject( - final AgentSpanContext context, final C carrier, final Setter setter) {} - - @Override - public void inject( - AgentSpan span, C carrier, Setter setter, TracePropagationStyle style) {} - @Override public void injectPathwayContext( AgentSpan span, C carrier, Setter setter, LinkedHashMap sortedTags) {} @@ -612,11 +600,6 @@ public void injectPathwayContext( @Override public void injectPathwayContextWithoutSendingStats( AgentSpan span, C carrier, Setter setter, LinkedHashMap sortedTags) {} - - @Override - public AgentSpanContext.Extracted extract(final C carrier, final ContextVisitor getter) { - return NoopSpanContext.INSTANCE; - } } static class NoopContinuation implements AgentScope.Continuation { From 8a6781356ac2d06a1e22127430049dcdd7a5bd24 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Thu, 30 Jan 2025 13:56:30 +0100 Subject: [PATCH 2/4] feat(context): Improve composite propagator order --- .../java/datadog/context/propagation/CompositePropagator.java | 4 ++-- .../main/java/datadog/context/propagation/Propagators.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/components/context/src/main/java/datadog/context/propagation/CompositePropagator.java b/components/context/src/main/java/datadog/context/propagation/CompositePropagator.java index b24af3bd05b..9484b2a8054 100644 --- a/components/context/src/main/java/datadog/context/propagation/CompositePropagator.java +++ b/components/context/src/main/java/datadog/context/propagation/CompositePropagator.java @@ -14,8 +14,8 @@ class CompositePropagator implements Propagator { @Override public void inject(Context context, C carrier, CarrierSetter setter) { - for (Propagator propagator : this.propagators) { - propagator.inject(context, carrier, setter); + for (int i = this.propagators.length - 1; i >= 0; i--) { + this.propagators[i].inject(context, carrier, setter); } } diff --git a/components/context/src/main/java/datadog/context/propagation/Propagators.java b/components/context/src/main/java/datadog/context/propagation/Propagators.java index d29867251b5..cbf1bd0ae5f 100644 --- a/components/context/src/main/java/datadog/context/propagation/Propagators.java +++ b/components/context/src/main/java/datadog/context/propagation/Propagators.java @@ -78,7 +78,8 @@ public static Propagator noop() { * Creates a composite propagator. * * @param propagators the elements that composes the returned propagator. - * @return the composite propagator that will apply the propagators in their given order. + * @return the composite propagator that will apply the propagators in their given order for + * context extraction, and reverse given order for context injection. */ public static Propagator composite(Propagator... propagators) { if (propagators.length == 0) { From 3f491cbc415d6b2803460d6f553e1bd92f4e0159 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Wed, 29 Jan 2025 15:17:32 +0100 Subject: [PATCH 3/4] chore(api): Simplify span link test --- .../trace/bootstrap/instrumentation/api/SpanLinkTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/SpanLinkTest.groovy b/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/SpanLinkTest.groovy index 56057d8b16a..a1e9b93ca38 100644 --- a/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/SpanLinkTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/SpanLinkTest.groovy @@ -3,12 +3,12 @@ package datadog.trace.bootstrap.instrumentation.api import datadog.trace.api.DDSpanId import datadog.trace.api.DDTraceId -import datadog.trace.test.util.DDSpecification +import spock.lang.Specification import static datadog.trace.bootstrap.instrumentation.api.AgentSpanLink.DEFAULT_FLAGS import static datadog.trace.bootstrap.instrumentation.api.AgentSpanLink.SAMPLED_FLAG -class SpanLinkTest extends DDSpecification { +class SpanLinkTest extends Specification { def "test span link from context"() { setup: def traceId = DDTraceId.fromHex("11223344556677889900aabbccddeeff") From 9f13521b29cc4dc2a20f0634d3ef49bb75414210 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Mon, 27 Jan 2025 15:08:34 +0100 Subject: [PATCH 4/4] feat(core): Move DSM extractor to its own propagator --- dd-trace-core/build.gradle | 4 + .../java/datadog/trace/core/CoreTracer.java | 20 +- .../datastreams/DataStreamPropagator.java | 83 +++++++ .../datastreams/DataStreamsMonitoring.java | 8 + .../DefaultDataStreamsMonitoring.java | 7 + .../datastreams/DefaultPathwayContext.java | 15 +- .../core/propagation/CorePropagation.java | 6 +- .../propagation/CorePropagationTest.groovy | 220 ------------------ .../instrumentation/api/AgentPropagation.java | 4 + 9 files changed, 126 insertions(+), 241 deletions(-) create mode 100644 dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamPropagator.java delete mode 100644 dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy diff --git a/dd-trace-core/build.gradle b/dd-trace-core/build.gradle index e3c34a531f0..cfc50ded09b 100644 --- a/dd-trace-core/build.gradle +++ b/dd-trace-core/build.gradle @@ -48,6 +48,10 @@ excludedClassesCoverage += [ 'datadog.trace.core.TracingConfigPoller.Updater', // covered with dd-trace-core/src/test/groovy/datadog/trace/core/datastreams/CheckpointerTest.groovy 'datadog.trace.core.datastreams.DefaultDataStreamsMonitoring', + // TODO CorePropagation will be removed during context refactoring + 'datadog.trace.core.propagation.CorePropagation', + // TODO DSM propagator will be tested once fully migrated + 'datadog.trace.core.datastreams.DataStreamPropagator' ] addTestSuite('traceAgentTest') diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 3f5c5264a72..09d578d06d0 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -5,6 +5,7 @@ import static datadog.trace.api.DDTags.DJM_ENABLED; import static datadog.trace.api.DDTags.DSM_ENABLED; import static datadog.trace.api.DDTags.PROFILING_CONTEXT_ENGINE; +import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.DSM_CONCERN; import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.STANDALONE_ASM_CONCERN; import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.TRACING_CONCERN; import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.XRAY_TRACING_CONCERN; @@ -713,22 +714,25 @@ private CoreTracer( sharedCommunicationObjects.whenReady(this.dataStreamsMonitoring::start); - // Create default extractor from config if not provided and decorate it with DSM extractor - HttpCodec.Extractor builtExtractor = - extractor == null ? HttpCodec.createExtractor(config, this::captureTraceConfig) : extractor; - builtExtractor = this.dataStreamsMonitoring.extractor(builtExtractor); - // Store all propagators to propagation - this.propagation = new CorePropagation(builtExtractor, this.dataStreamsMonitoring.injector()); + // Store all propagators to propagation -- only DSM injection left + this.propagation = new CorePropagation(this.dataStreamsMonitoring.injector()); + // Register context propagators + HttpCodec.Extractor tracingExtractor = + extractor == null ? HttpCodec.createExtractor(config, this::captureTraceConfig) : extractor; + TracingPropagator tracingPropagator = new TracingPropagator(injector, tracingExtractor); // Check if standalone AppSec is enabled: // If enabled, use the standalone AppSec propagator by default that will limit tracing concern // injection and delegate to the tracing propagator if needed, // If disabled, the most common case, use the usual tracing propagator by default. boolean standaloneAppSec = config.isAppSecStandaloneEnabled(); + boolean dsm = config.isDataStreamsEnabled(); Propagators.register(STANDALONE_ASM_CONCERN, new StandaloneAsmPropagator(), standaloneAppSec); - Propagators.register( - TRACING_CONCERN, new TracingPropagator(injector, extractor), !standaloneAppSec); + Propagators.register(TRACING_CONCERN, tracingPropagator, !standaloneAppSec); Propagators.register(XRAY_TRACING_CONCERN, new XRayPropagator(config), false); + if (dsm) { + Propagators.register(DSM_CONCERN, this.dataStreamsMonitoring.propagator()); + } this.tagInterceptor = null == tagInterceptor ? new TagInterceptor(new RuleFlags(config)) : tagInterceptor; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamPropagator.java b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamPropagator.java new file mode 100644 index 00000000000..7fdedfad381 --- /dev/null +++ b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamPropagator.java @@ -0,0 +1,83 @@ +package datadog.trace.core.datastreams; + +import datadog.context.Context; +import datadog.context.propagation.CarrierSetter; +import datadog.context.propagation.CarrierVisitor; +import datadog.context.propagation.Propagator; +import datadog.trace.api.TraceConfig; +import datadog.trace.api.time.TimeSource; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext; +import datadog.trace.bootstrap.instrumentation.api.PathwayContext; +import datadog.trace.bootstrap.instrumentation.api.TagContext; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +// TODO Javadoc +@ParametersAreNonnullByDefault +public class DataStreamPropagator implements Propagator { + private final Supplier traceConfigSupplier; + private final TimeSource timeSource; + private final long hashOfKnownTags; + private final String serviceNameOverride; + + public DataStreamPropagator( + Supplier traceConfigSupplier, + TimeSource timeSource, + long hashOfKnownTags, + String serviceNameOverride) { + this.traceConfigSupplier = traceConfigSupplier; + this.timeSource = timeSource; + this.hashOfKnownTags = hashOfKnownTags; + this.serviceNameOverride = serviceNameOverride; + } + + @Override + public void inject(Context context, C carrier, CarrierSetter setter) { + // TODO Still in CorePropagation, not migrated yet + } + + @Override + public Context extract(Context context, C carrier, CarrierVisitor visitor) { + // TODO Pathway context needs to be stored into its own context element + // Get span context to store pathway context into + TagContext spanContext = getSpanContextOrNull(context); + PathwayContext pathwayContext; + // Ensure if DSM is enabled and look for pathway context + if (isDsmEnabled(spanContext) + && (pathwayContext = extractDsmPathwayContext(carrier, visitor)) != null) { + // Store pathway context into span context + if (spanContext == null) { + spanContext = new TagContext(); + AgentSpan span = AgentSpan.fromSpanContext(spanContext); + context = Context.root().with(span); + } + spanContext.withPathwayContext(pathwayContext); + } + return context; + } + + private TagContext getSpanContextOrNull(Context context) { + AgentSpan extractedSpan = AgentSpan.fromContext(context); + AgentSpanContext extractedSpanContext; + if (extractedSpan != null + && (extractedSpanContext = extractedSpan.context()) instanceof TagContext) { + return (TagContext) extractedSpanContext; + } + return null; + } + + private boolean isDsmEnabled(@Nullable TagContext tagContext) { + TraceConfig traceConfig = tagContext == null ? null : tagContext.getTraceConfig(); + if (traceConfig == null) { + traceConfig = this.traceConfigSupplier.get(); + } + return traceConfig.isDataStreamsEnabled(); + } + + private PathwayContext extractDsmPathwayContext(C carrier, CarrierVisitor visitor) { + return DefaultPathwayContext.extract( + carrier, visitor, this.timeSource, this.hashOfKnownTags, this.serviceNameOverride); + } +} diff --git a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamsMonitoring.java b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamsMonitoring.java index c7039bac92e..0571eff5f08 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamsMonitoring.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DataStreamsMonitoring.java @@ -1,5 +1,6 @@ package datadog.trace.core.datastreams; +import datadog.context.propagation.Propagator; import datadog.trace.api.experimental.DataStreamsContextCarrier; import datadog.trace.bootstrap.instrumentation.api.AgentDataStreamsMonitoring; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -10,6 +11,13 @@ public interface DataStreamsMonitoring extends AgentDataStreamsMonitoring, AutoCloseable { void start(); + /** + * Gets the propagator for DSM concern. + * + * @return The propagator for DSM concern. + */ + Propagator propagator(); + /** * Get a context extractor that support {@link PathwayContext} extraction. * diff --git a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultDataStreamsMonitoring.java b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultDataStreamsMonitoring.java index 00b9c4504b4..2c8a897e762 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultDataStreamsMonitoring.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultDataStreamsMonitoring.java @@ -14,6 +14,7 @@ import datadog.communication.ddagent.DDAgentFeaturesDiscovery; import datadog.communication.ddagent.SharedCommunicationObjects; +import datadog.context.propagation.Propagator; import datadog.trace.api.Config; import datadog.trace.api.TraceConfig; import datadog.trace.api.WellKnownTags; @@ -200,6 +201,12 @@ public PathwayContext newPathwayContext() { } } + @Override + public Propagator propagator() { + return new DataStreamPropagator( + this.traceConfigSupplier, this.timeSource, this.hashOfKnownTags, getThreadServiceName()); + } + @Override public HttpCodec.Extractor extractor(HttpCodec.Extractor delegate) { return new DataStreamContextExtractor( diff --git a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultPathwayContext.java b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultPathwayContext.java index 3f3ddf9d725..b95a65926dc 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultPathwayContext.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/datastreams/DefaultPathwayContext.java @@ -7,10 +7,10 @@ import com.datadoghq.sketch.ddsketch.encoding.ByteArrayInput; import com.datadoghq.sketch.ddsketch.encoding.GrowingByteArrayOutput; import com.datadoghq.sketch.ddsketch.encoding.VarEncodingHelper; +import datadog.context.propagation.CarrierVisitor; import datadog.trace.api.Config; import datadog.trace.api.WellKnownTags; import datadog.trace.api.time.TimeSource; -import datadog.trace.bootstrap.instrumentation.api.AgentPropagation; import datadog.trace.bootstrap.instrumentation.api.PathwayContext; import datadog.trace.bootstrap.instrumentation.api.StatsPoint; import datadog.trace.util.FNV64Hash; @@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BiConsumer; import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -267,7 +268,7 @@ public String toString() { } } - private static class PathwayContextExtractor implements AgentPropagation.KeyClassifier { + private static class PathwayContextExtractor implements BiConsumer { private final TimeSource timeSource; private final long hashOfKnownTags; private final String serviceNameOverride; @@ -281,27 +282,25 @@ private static class PathwayContextExtractor implements AgentPropagation.KeyClas } @Override - public boolean accept(String key, String value) { + public void accept(String key, String value) { if (PROPAGATION_KEY_BASE64.equalsIgnoreCase(key)) { try { extractedContext = decode(timeSource, hashOfKnownTags, serviceNameOverride, value); - } catch (IOException e) { - return false; + } catch (IOException ignored) { } } - return true; } } static DefaultPathwayContext extract( C carrier, - AgentPropagation.ContextVisitor getter, + CarrierVisitor getter, TimeSource timeSource, long hashOfKnownTags, String serviceNameOverride) { PathwayContextExtractor pathwayContextExtractor = new PathwayContextExtractor(timeSource, hashOfKnownTags, serviceNameOverride); - getter.forEachKey(carrier, pathwayContextExtractor); + getter.forEachKeyValue(carrier, pathwayContextExtractor); if (pathwayContextExtractor.extractedContext == null) { log.debug("No context extracted"); } else { diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java index d2379bb7e2c..90f43736c38 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/CorePropagation.java @@ -7,18 +7,14 @@ public class CorePropagation implements AgentPropagation { private final DataStreamContextInjector dataStreamContextInjector; - private final HttpCodec.Extractor extractor; /** * Constructor * - * @param extractor The context extractor. * @param dataStreamContextInjector The DSM context injector, as a specific object until generic * context injection is available. */ - public CorePropagation( - HttpCodec.Extractor extractor, DataStreamContextInjector dataStreamContextInjector) { - this.extractor = extractor; + public CorePropagation(DataStreamContextInjector dataStreamContextInjector) { this.dataStreamContextInjector = dataStreamContextInjector; } diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy deleted file mode 100644 index ec170a2bc6d..00000000000 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/CorePropagationTest.groovy +++ /dev/null @@ -1,220 +0,0 @@ -package datadog.trace.core.propagation - -import datadog.trace.bootstrap.instrumentation.api.AgentPropagation -import datadog.trace.core.datastreams.DataStreamContextInjector -import datadog.trace.core.test.DDCoreSpecification - -class CorePropagationTest extends DDCoreSpecification { - HttpCodec.Extractor extractor - // HttpCodec.Injector datadogInjector - // HttpCodec.Injector b3Injector - // HttpCodec.Injector traceContextInjector - // Map allInjectors - DataStreamContextInjector dataStreamContextInjector - AgentPropagation propagation - - def setup() { - extractor = Mock(HttpCodec.Extractor) - // datadogInjector = Mock(HttpCodec.Injector) - // b3Injector = Mock(HttpCodec.Injector) - // traceContextInjector = Mock(HttpCodec.Injector) - // allInjectors = [ - // (DATADOG) : datadogInjector, - // (B3MULTI) : b3Injector, - // (TRACECONTEXT): traceContextInjector, - // ] - dataStreamContextInjector = Mock(DataStreamContextInjector) - propagation = new CorePropagation(extractor, dataStreamContextInjector) - } - - // def 'test default injector for span'() { - // setup: - // def tracer = tracerBuilder().build() - // def span = tracer.buildSpan('test', 'operation').start() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // propagation.inject(span, carrier, setter) - // - // then: - // 1 * datadogInjector.inject(_, carrier, setter) - // 0 * b3Injector.inject(_, carrier, setter) - // 0 * traceContextInjector.inject(_, carrier, setter) - // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - // - // cleanup: - // span.finish() - // tracer.close() - // } - // - // def 'test default injector for span context'() { - // setup: - // def tracer = tracerBuilder().build() - // def span = tracer.buildSpan("test", "operation").start() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // def spanContext = span.context() - // propagation.inject(spanContext, carrier, setter) - // - // then: - // 1 * datadogInjector.inject(_, carrier, setter) - // 0 * b3Injector.inject(_, carrier, setter) - // 0 * traceContextInjector.inject(_, carrier, setter) - // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - // - // cleanup: - // span.finish() - // tracer.close() - // } - // - // def 'test injector style selection'() { - // setup: - // def injector = allInjectors.get(style, datadogInjector) - // def tracer = tracerBuilder().build() - // def span = tracer.buildSpan('test', 'operation').start() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // propagation.inject(span, carrier, setter, style) - // - // then: - // 1 * injector.inject(_, carrier, setter) - // if (injector != datadogInjector) { - // 0 * datadogInjector.inject(_, carrier, setter) - // } - // if (injector != b3Injector) { - // 0 * b3Injector.inject(_, carrier, setter) - // } - // if (injector != traceContextInjector) { - // 0 * traceContextInjector.inject(_, carrier, setter) - // } - // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - // - // cleanup: - // span.finish() - // tracer.close() - // - // where: - // style << [DATADOG, B3MULTI, TRACECONTEXT, null] - // } - - def 'test context extractor'() { - setup: - def getter = Mock(AgentPropagation.ContextVisitor) - def carrier = new Object() - - when: - propagation.extract(carrier, getter) - - then: - 1 * extractor.extract(carrier, getter) - } - - // def 'span priority set when injecting'() { - // given: - // injectSysConfig('writer.type', 'LoggingWriter') - // def tracer = tracerBuilder().build() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // def root = tracer.buildSpan('test', 'operation').start() - // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - // tracer.propagate().inject(child, carrier, setter) - // - // then: - // root.getSamplingPriority() == SAMPLER_KEEP as int - // child.getSamplingPriority() == root.getSamplingPriority() - // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - // - // cleanup: - // child.finish() - // root.finish() - // tracer.close() - // } - // - // def 'span priority only set after first injection'() { - // given: - // def sampler = new ControllableSampler() - // def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // def root = tracer.buildSpan('test', 'operation').start() - // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - // tracer.propagate().inject(child, carrier, setter) - // - // then: - // root.getSamplingPriority() == SAMPLER_KEEP as int - // child.getSamplingPriority() == root.getSamplingPriority() - // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - // - // when: - // sampler.nextSamplingPriority = PrioritySampling.SAMPLER_DROP as int - // def child2 = tracer.buildSpan('test', 'my_child2').asChildOf(root).start() - // tracer.propagate().inject(child2, carrier, setter) - // - // then: - // root.getSamplingPriority() == SAMPLER_KEEP as int - // child.getSamplingPriority() == root.getSamplingPriority() - // child2.getSamplingPriority() == root.getSamplingPriority() - // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(SAMPLER_KEEP)) - // - // cleanup: - // child.finish() - // child2.finish() - // root.finish() - // tracer.close() - // } - // - // def "injection doesn't override set priority"() { - // given: - // def sampler = new ControllableSampler() - // def tracer = tracerBuilder().writer(new LoggingWriter()).sampler(sampler).build() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // def root = tracer.buildSpan('test', 'operation').start() - // def child = tracer.buildSpan('test', 'my_child').asChildOf(root).start() - // child.setSamplingPriority(PrioritySampling.USER_DROP) - // tracer.propagate().inject(child, carrier, setter) - // - // then: - // root.getSamplingPriority() == PrioritySampling.USER_DROP as int - // child.getSamplingPriority() == root.getSamplingPriority() - // 1 * setter.set(carrier, DatadogHttpCodec.SAMPLING_PRIORITY_KEY, String.valueOf(PrioritySampling.USER_DROP)) - // - // cleanup: - // child.finish() - // root.finish() - // tracer.close() - // } - // - // def 'test ASM standalone billing stop propagation'() { - // setup: - // injectSysConfig("experimental.appsec.standalone.enabled", "true") - // def tracer = tracerBuilder().build() - // def span = tracer.buildSpan('test', 'operation').start() - // def setter = Mock(AgentPropagation.Setter) - // def carrier = new Object() - // - // when: - // propagation.inject(span, carrier, setter) - // - // then: - // 0 * datadogInjector.inject(_, carrier, setter) - // 0 * b3Injector.inject(_, carrier, setter) - // 0 * traceContextInjector.inject(_, carrier, setter) - // 0 * dataStreamContextInjector.injectPathwayContext(_, carrier, setter, _) - // - // cleanup: - // span.finish() - // tracer.close() - // } -} diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java index d0333e2d906..0fd8cbca94f 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentPropagation.java @@ -1,6 +1,7 @@ package datadog.trace.bootstrap.instrumentation.api; import static datadog.context.propagation.Concern.named; +import static datadog.context.propagation.Concern.withPriority; import datadog.context.Context; import datadog.context.propagation.CarrierSetter; @@ -15,6 +16,9 @@ public interface AgentPropagation { Concern TRACING_CONCERN = named("tracing"); Concern XRAY_TRACING_CONCERN = named("tracing-xray"); Concern STANDALONE_ASM_CONCERN = named("asm-standalone"); + // TODO DSM propagator should run after the other propagators as it stores the pathway context + // TODO into the span context for now. Remove priority after the migration is complete. + Concern DSM_CONCERN = withPriority("data-stream-monitoring", 110); // The input tags should be sorted. void injectPathwayContext(