Skip to content

Commit 4bc78b1

Browse files
committed
feat(tracer): Introduce eager span tag processors
1 parent 0c0dd50 commit 4bc78b1

10 files changed

Lines changed: 66 additions & 53 deletions

File tree

dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ public interface CoreSpan<T extends CoreSpan<T>> {
6868

6969
CharSequence getType();
7070

71+
/**
72+
* Runs early {@link datadog.trace.core.tagprocessor.TagsPostProcessor} like base service and peer
73+
* service computation. Such tags are needed before span serialization so they can’t be processed
74+
* lazily as part of the {@link #processTagsAndBaggage(MetadataConsumer)} API.
75+
*/
76+
void processServiceTags();
77+
7178
void processTagsAndBaggage(MetadataConsumer consumer);
7279

7380
T setSamplingPriority(int samplingPriority, int samplingMechanism);

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@
9797
import datadog.trace.core.scopemanager.ContinuableScopeManager;
9898
import datadog.trace.core.taginterceptor.RuleFlags;
9999
import datadog.trace.core.taginterceptor.TagInterceptor;
100-
import datadog.trace.core.tagprocessor.BaseServiceAdder;
101-
import datadog.trace.core.tagprocessor.PeerServiceCalculator;
102-
import datadog.trace.core.tagprocessor.PostProcessorChain;
103-
import datadog.trace.core.tagprocessor.TagsPostProcessor;
104100
import datadog.trace.core.traceinterceptor.LatencyTraceInterceptor;
105101
import datadog.trace.lambda.LambdaHandler;
106102
import datadog.trace.relocate.api.RatelimitedLogger;
@@ -203,8 +199,6 @@ public static CoreTracerBuilder builder() {
203199

204200
private final boolean defaultSpanTagsNeedsIntercept;
205201

206-
public final PostProcessorChain preWritePostProcessorChain;
207-
208202
/** number of spans in a pending trace before they get flushed */
209203
private final int partialFlushMinSpans;
210204

@@ -326,7 +320,6 @@ public static class CoreTracerBuilder {
326320
private StatsDClient statsDClient;
327321
private HealthMetrics healthMetrics;
328322
private TagInterceptor tagInterceptor;
329-
private List<TagsPostProcessor> preWriteTagsPostProcessors;
330323
private boolean strictTraceWrites;
331324
private InstrumentationGateway instrumentationGateway;
332325
private TimeSource timeSource;
@@ -429,12 +422,6 @@ public CoreTracerBuilder tagInterceptor(TagInterceptor tagInterceptor) {
429422
return this;
430423
}
431424

432-
public CoreTracerBuilder preWriteTagsPostProcessors(
433-
List<TagsPostProcessor> preWriteTagsPostProcessors) {
434-
this.preWriteTagsPostProcessors = preWriteTagsPostProcessors;
435-
return this;
436-
}
437-
438425
public CoreTracerBuilder healthMetrics(HealthMetrics healthMetrics) {
439426
this.healthMetrics = healthMetrics;
440427
return this;
@@ -540,7 +527,6 @@ public CoreTracer build() {
540527
statsDClient,
541528
healthMetrics,
542529
tagInterceptor,
543-
preWriteTagsPostProcessors,
544530
strictTraceWrites,
545531
instrumentationGateway,
546532
timeSource,
@@ -601,7 +587,6 @@ private CoreTracer(
601587
statsDClient,
602588
healthMetrics,
603589
tagInterceptor,
604-
null,
605590
strictTraceWrites,
606591
instrumentationGateway,
607592
timeSource,
@@ -633,7 +618,6 @@ private CoreTracer(
633618
final StatsDClient statsDClient,
634619
final HealthMetrics healthMetrics,
635620
final TagInterceptor tagInterceptor,
636-
final List<TagsPostProcessor> preWriteTagsPostProcessors,
637621
final boolean strictTraceWrites,
638622
final InstrumentationGateway instrumentationGateway,
639623
final TimeSource timeSource,
@@ -683,15 +667,6 @@ private CoreTracer(
683667
this.tagInterceptor =
684668
null == tagInterceptor ? new TagInterceptor(new RuleFlags(config)) : tagInterceptor;
685669

686-
if (preWriteTagsPostProcessors != null) {
687-
this.preWritePostProcessorChain =
688-
new PostProcessorChain(preWriteTagsPostProcessors.toArray(new TagsPostProcessor[0]));
689-
} else {
690-
this.preWritePostProcessorChain =
691-
new PostProcessorChain(
692-
new PeerServiceCalculator(), new BaseServiceAdder(Config.get().getServiceName()));
693-
}
694-
695670
this.defaultSpanTags = defaultSpanTags;
696671
this.defaultSpanTagsNeedsIntercept = this.tagInterceptor.needsIntercept(this.defaultSpanTags);
697672

@@ -1138,9 +1113,7 @@ void write(final List<DDSpan> trace) {
11381113
// run early tag postprocessors before publishing to the metrics writer since peer / base
11391114
// service are needed
11401115
for (DDSpan span : writtenTrace) {
1141-
final DDSpanContext ddSpanContext = span.context();
1142-
preWritePostProcessorChain.processTags(
1143-
ddSpanContext.unsafeGetTags(), ddSpanContext, span.getSpanLinks());
1116+
span.processServiceTags();
11441117
}
11451118
boolean forceKeep = metricsAggregator.publish(writtenTrace);
11461119

dd-trace-core/src/main/java/datadog/trace/core/DDSpan.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ public String getSpanType() {
694694

695695
@Override
696696
public TagMap getTags() {
697-
// This is an imutable copy of the tags
697+
// This is an immutable copy of the tags
698698
return context.getTags();
699699
}
700700

@@ -703,6 +703,11 @@ public CharSequence getType() {
703703
return context.getSpanType();
704704
}
705705

706+
@Override
707+
public void processServiceTags() {
708+
context.earlyProcessTags(links);
709+
}
710+
706711
@Override
707712
public void processTagsAndBaggage(final MetadataConsumer consumer) {
708713
context.processTagsAndBaggage(consumer, longRunningVersion, links);
@@ -826,10 +831,6 @@ public void addLink(AgentSpanLink link) {
826831
}
827832
}
828833

829-
List<AgentSpanLink> getSpanLinks() {
830-
return links;
831-
}
832-
833834
// to be accessible in Spock spies, which the field wouldn't otherwise be
834835
public long getStartTimeNano() {
835836
return startTimeNano;

dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,6 @@ public TagMap getTags() {
897897
}
898898
}
899899

900-
TagMap unsafeGetTags() {
901-
return unsafeTags;
902-
}
903-
904900
/** @see CoreSpan#getMetaStruct() */
905901
public Map<String, Object> getMetaStruct() {
906902
return Collections.unmodifiableMap(metaStruct);
@@ -925,11 +921,17 @@ public <T> void setMetaStruct(final String field, final T value) {
925921
}
926922
}
927923

924+
public void earlyProcessTags(List<AgentSpanLink> links) {
925+
synchronized (unsafeTags) {
926+
TagsPostProcessorFactory.eagerProcessor().processTags(unsafeTags, this, links);
927+
}
928+
}
929+
928930
public void processTagsAndBaggage(
929931
final MetadataConsumer consumer, int longRunningVersion, List<AgentSpanLink> links) {
930932
synchronized (unsafeTags) {
931933
// Tags
932-
TagsPostProcessorFactory.instance().processTags(unsafeTags, this, links);
934+
TagsPostProcessorFactory.lazyProcessor().processTags(unsafeTags, this, links);
933935

934936
String linksTag = DDSpanLink.toTag(links);
935937
if (linksTag != null) {

dd-trace-core/src/main/java/datadog/trace/core/tagprocessor/TagsPostProcessorFactory.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,23 @@
55
import java.util.List;
66

77
public final class TagsPostProcessorFactory {
8+
private static boolean addBaseService = true;
89
private static boolean addRemoteHostname = true;
910

1011
private static class Lazy {
11-
private static TagsPostProcessor create() {
12+
private static TagsPostProcessor eagerProcessor = createEagerChain();
13+
private static TagsPostProcessor lazyProcessor = createLazyChain();
14+
15+
private static TagsPostProcessor createEagerChain() {
16+
final List<TagsPostProcessor> processors = new ArrayList<>(2);
17+
processors.add(new PeerServiceCalculator());
18+
if (addBaseService) {
19+
processors.add(new BaseServiceAdder(Config.get().getServiceName()));
20+
}
21+
return new PostProcessorChain(processors.toArray(new TagsPostProcessor[0]));
22+
}
23+
24+
private static TagsPostProcessor createLazyChain() {
1225
final List<TagsPostProcessor> processors = new ArrayList<>(7);
1326

1427
processors.add(new QueryObfuscator(Config.get().getObfuscationQueryRegexp()));
@@ -32,12 +45,24 @@ private static TagsPostProcessor create() {
3245
return new PostProcessorChain(
3346
processors.toArray(processors.toArray(new TagsPostProcessor[0])));
3447
}
48+
}
3549

36-
private static TagsPostProcessor instance = create();
50+
public static TagsPostProcessor eagerProcessor() {
51+
return Lazy.eagerProcessor;
3752
}
3853

39-
public static TagsPostProcessor instance() {
40-
return Lazy.instance;
54+
public static TagsPostProcessor lazyProcessor() {
55+
return Lazy.lazyProcessor;
56+
}
57+
58+
/**
59+
* Mostly used for test purposes.
60+
*
61+
* @param enabled if false, {@link BaseServiceAdder} is not put in the chain.
62+
*/
63+
public static void withAddBaseService(boolean enabled) {
64+
addBaseService = enabled;
65+
Lazy.eagerProcessor = Lazy.createEagerChain();
4166
}
4267

4368
/**
@@ -47,11 +72,12 @@ public static TagsPostProcessor instance() {
4772
*/
4873
public static void withAddRemoteHostname(boolean enabled) {
4974
addRemoteHostname = enabled;
50-
Lazy.instance = Lazy.create();
75+
Lazy.lazyProcessor = Lazy.createLazyChain();
5176
}
5277

5378
/** Used for testing purposes. It reset the singleton and restore default options */
5479
public static void reset() {
80+
withAddBaseService(true);
5581
withAddRemoteHostname(true);
5682
}
5783
}

dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ class SimpleSpan implements CoreSpan<SimpleSpan> {
206206
return type
207207
}
208208

209+
@Override
210+
void processServiceTags() {}
211+
209212
@Override
210213
void processTagsAndBaggage(MetadataConsumer consumer) {}
211214

dd-trace-core/src/test/groovy/datadog/trace/common/writer/TraceGenerator.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ class TraceGenerator {
333333
return this.type
334334
}
335335

336+
@Override
337+
void processServiceTags() {}
338+
336339
@Override
337340
void processTagsAndBaggage(MetadataConsumer consumer) {
338341
consumer.accept(metadata)

dd-trace-core/src/test/groovy/datadog/trace/core/CoreTracerTest.groovy

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import datadog.trace.common.sampling.Sampler
1919
import datadog.trace.common.writer.DDAgentWriter
2020
import datadog.trace.common.writer.ListWriter
2121
import datadog.trace.common.writer.LoggingWriter
22-
import datadog.trace.core.tagprocessor.BaseServiceAdder
22+
import datadog.trace.core.tagprocessor.TagsPostProcessorFactory
2323
import datadog.trace.core.test.DDCoreSpecification
2424
import okhttp3.HttpUrl
2525
import okhttp3.OkHttpClient
@@ -544,10 +544,8 @@ class CoreTracerTest extends DDCoreSpecification {
544544
setup:
545545
injectSysConfig(SERVICE_NAME, "dd_service_name")
546546
injectSysConfig(VERSION, "1.0.0")
547-
def tracer = tracerBuilder()
548-
.writer(new ListWriter())
549-
.preWriteTagsPostProcessors([new BaseServiceAdder("dd_service_name")])
550-
.build()
547+
TagsPostProcessorFactory.withAddBaseService(true)
548+
def tracer = tracerBuilder().writer(new ListWriter()).build()
551549

552550
when:
553551
def span = tracer.buildSpan("def").withTag(SERVICE_NAME,"foo").start()

dd-trace-core/src/test/groovy/datadog/trace/core/test/DDCoreSpecification.groovy

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package datadog.trace.core.test
22

3-
import static java.util.Collections.emptyList
4-
53
import datadog.trace.api.DDSpanId
64
import datadog.trace.api.DDTraceId
75
import datadog.trace.api.StatsDClient
@@ -29,6 +27,7 @@ abstract class DDCoreSpecification extends DDSpecification {
2927

3028
@Override
3129
void setupSpec() {
30+
TagsPostProcessorFactory.withAddBaseService(false)
3231
TagsPostProcessorFactory.withAddRemoteHostname(false)
3332
}
3433

@@ -42,9 +41,7 @@ abstract class DDCoreSpecification extends DDSpecification {
4241
if (useNoopStatsDClient()) {
4342
builder = builder.statsDClient(StatsDClient.NO_OP)
4443
}
45-
return builder
46-
.strictTraceWrites(useStrictTraceWrites())
47-
.preWriteTagsPostProcessors(emptyList())
44+
return builder.strictTraceWrites(useStrictTraceWrites())
4845
}
4946

5047
protected DDSpan buildSpan(long timestamp, CharSequence spanType, Map<String, Object> tags) {

dd-trace-core/src/traceAgentTest/groovy/TraceGenerator.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ class TraceGenerator {
309309
return type
310310
}
311311

312+
@Override
313+
void processServiceTags() {}
314+
312315
@Override
313316
void processTagsAndBaggage(MetadataConsumer consumer) {
314317
consumer.accept(metadata)

0 commit comments

Comments
 (0)