Skip to content

Commit 38ba446

Browse files
mccullsdevflow.devflow-routing-intake
andauthored
Provide optimized writers for OpenTelemetry's "trace.proto" wire protocol (#11120)
Provide optimized writers for OpenTelemetry's "trace.proto" wire protocol Relax unboxing of number types in Otel attributes Only write W3CTracestate when available Remove incorrect check which only exported spans with links Test OtlpTraceProto with various span data, including different numbers of links Extend test to check 128 trace-ids and span link attributes Extend test to check link tracestate, traceflags, and span origin Re-use writeSpanTag Use logging trace writer during OtlpTraceProtoTest Disable injection of span-links as tags when using OTLP since we can send them as first-class links (likewise turn off legacy baggage injection) Cleanup Review feedback: support collecting multiple traces into one payload Add test to check multiple traces can be marshalled into a single payload Spelling Map no span.kind to UNSPECIFIED Review feedback: avoid NPE if value cache is turned off Review feedback: avoid cast exception if span.kind set to non-string value Review feedback: avoid capturing lambda by using TagMap.forEach that takes an extra context object Simple equality test is enough here Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
1 parent cae8110 commit 38ba446

File tree

17 files changed

+2208
-53
lines changed

17 files changed

+2208
-53
lines changed

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public final class ConfigDefaults {
4747
public static final boolean DEFAULT_STARTUP_LOGS_ENABLED = true;
4848

4949
static final boolean DEFAULT_INJECT_DATADOG_ATTRIBUTE = true;
50-
static final boolean DEFAULT_WRITER_BAGGAGE_INJECT = true;
5150
static final String DEFAULT_SITE = "datadoghq.com";
5251

5352
static final boolean DEFAULT_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT = false;

dd-trace-api/src/main/java/datadog/trace/api/config/TracerConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public final class TracerConfig {
1717
public static final String ID_GENERATION_STRATEGY = "id.generation.strategy";
1818
public static final String WRITER_TYPE = "writer.type";
1919
public static final String WRITER_BAGGAGE_INJECT = "writer.baggage.inject";
20+
public static final String WRITER_LINKS_INJECT = "writer.links.inject";
2021

2122
public static final String PRIORITIZATION_TYPE = "prioritization.type";
2223
public static final String TRACE_AGENT_URL = "trace.agent.url";

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ public static final CoreTracerBuilder builder() {
210210
private final TimeSource timeSource;
211211
private final ProfilingContextIntegration profilingContextIntegration;
212212
private final boolean injectBaggageAsTags;
213+
private final boolean injectLinksAsTags;
213214
private final boolean flushOnClose;
214215
private final Collection<Runnable> shutdownListeners = new CopyOnWriteArrayList<>();
215216

@@ -327,6 +328,7 @@ public static class CoreTracerBuilder {
327328
private boolean reportInTracerFlare;
328329
private boolean pollForTracingConfiguration;
329330
private boolean injectBaggageAsTags;
331+
private boolean injectLinksAsTags;
330332
private boolean flushOnClose;
331333

332334
public CoreTracerBuilder serviceName(String serviceName) {
@@ -472,6 +474,11 @@ public CoreTracerBuilder injectBaggageAsTags(boolean injectBaggageAsTags) {
472474
return this;
473475
}
474476

477+
public CoreTracerBuilder injectLinksAsTags(boolean injectLinksAsTags) {
478+
this.injectLinksAsTags = injectLinksAsTags;
479+
return this;
480+
}
481+
475482
public CoreTracerBuilder flushOnClose(boolean flushOnClose) {
476483
this.flushOnClose = flushOnClose;
477484
return this;
@@ -507,6 +514,7 @@ public CoreTracerBuilder config(final Config config) {
507514
partialFlushMinSpans(config.getPartialFlushMinSpans());
508515
strictTraceWrites(config.isTraceStrictWritesEnabled());
509516
injectBaggageAsTags(config.isInjectBaggageAsTagsEnabled());
517+
injectLinksAsTags(config.isInjectLinksAsTagsEnabled());
510518
flushOnClose(config.isCiVisibilityEnabled());
511519
return this;
512520
}
@@ -539,6 +547,7 @@ public CoreTracer build() {
539547
reportInTracerFlare,
540548
pollForTracingConfiguration,
541549
injectBaggageAsTags,
550+
injectLinksAsTags,
542551
flushOnClose);
543552
}
544553
}
@@ -570,6 +579,7 @@ private CoreTracer(
570579
final boolean reportInTracerFlare,
571580
final boolean pollForTracingConfiguration,
572581
final boolean injectBaggageAsTags,
582+
final boolean injectLinksAsTags,
573583
final boolean flushOnClose) {
574584
this(
575585
config,
@@ -598,6 +608,7 @@ private CoreTracer(
598608
reportInTracerFlare,
599609
pollForTracingConfiguration,
600610
injectBaggageAsTags,
611+
injectLinksAsTags,
601612
flushOnClose);
602613
}
603614

@@ -629,6 +640,7 @@ private CoreTracer(
629640
final boolean reportInTracerFlare,
630641
final boolean pollForTracingConfiguration,
631642
final boolean injectBaggageAsTags,
643+
final boolean injectLinksAsTags,
632644
final boolean flushOnClose) {
633645

634646
assert localRootSpanTags != null;
@@ -865,6 +877,7 @@ private CoreTracer(
865877
propagationTagsFactory = PropagationTags.factory(config);
866878
this.profilingContextIntegration = profilingContextIntegration;
867879
this.injectBaggageAsTags = injectBaggageAsTags;
880+
this.injectLinksAsTags = injectLinksAsTags;
868881
this.flushOnClose = flushOnClose;
869882
this.allowInferredServices = SpanNaming.instance().namingSchema().allowInferredServices();
870883
if (profilingContextIntegration != ProfilingContextIntegration.NoOp.INSTANCE) {
@@ -2132,7 +2145,8 @@ protected static final DDSpanContext buildSpanContext(
21322145
tracer.disableSamplingMechanismValidation,
21332146
propagationTags,
21342147
tracer.profilingContextIntegration,
2135-
tracer.injectBaggageAsTags);
2148+
tracer.injectBaggageAsTags,
2149+
tracer.injectLinksAsTags);
21362150

21372151
// By setting the tags on the context we apply decorators to any tags that have been set via
21382152
// the builder. This is the order that the tags were added previously, but maybe the `tags`

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ public TraceConfig traceConfig() {
883883
return context.getTraceCollector().getTraceConfig();
884884
}
885885

886-
List<? extends AgentSpanLink> getLinks() {
886+
public List<? extends AgentSpanLink> getLinks() {
887887
return this.links;
888888
}
889889

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ public class DDSpanContext
184184

185185
private final ProfilingContextIntegration profilingContextIntegration;
186186
private final boolean injectBaggageAsTags;
187+
private final boolean injectLinksAsTags;
187188
private volatile int encodedOperationName;
188189
private volatile int encodedResourceName;
189190

@@ -238,6 +239,7 @@ public DDSpanContext(
238239
disableSamplingMechanismValidation,
239240
propagationTags,
240241
ProfilingContextIntegration.NoOp.INSTANCE,
242+
true,
241243
true);
242244
}
243245

@@ -261,7 +263,8 @@ public DDSpanContext(
261263
final PathwayContext pathwayContext,
262264
final boolean disableSamplingMechanismValidation,
263265
final PropagationTags propagationTags,
264-
final boolean injectBaggageAsTags) {
266+
final boolean injectBaggageAsTags,
267+
final boolean injectLinksAsTags) {
265268
this(
266269
traceId,
267270
spanId,
@@ -286,7 +289,8 @@ public DDSpanContext(
286289
disableSamplingMechanismValidation,
287290
propagationTags,
288291
ProfilingContextIntegration.NoOp.INSTANCE,
289-
injectBaggageAsTags);
292+
injectBaggageAsTags,
293+
injectLinksAsTags);
290294
}
291295

292296
public DDSpanContext(
@@ -313,7 +317,8 @@ public DDSpanContext(
313317
final boolean disableSamplingMechanismValidation,
314318
final PropagationTags propagationTags,
315319
final ProfilingContextIntegration profilingContextIntegration,
316-
final boolean injectBaggageAsTags) {
320+
final boolean injectBaggageAsTags,
321+
final boolean injectLinksAsTags) {
317322

318323
assert traceCollector != null;
319324
this.traceCollector = traceCollector;
@@ -370,6 +375,7 @@ public DDSpanContext(
370375
: traceCollector.getTracer().getPropagationTagsFactory().empty();
371376
this.propagationTags.updateTraceIdHighOrderBits(this.traceId.toHighOrderLong());
372377
this.injectBaggageAsTags = injectBaggageAsTags;
378+
this.injectLinksAsTags = injectLinksAsTags;
373379
if (origin != null) {
374380
setOrigin(origin);
375381
}
@@ -1177,10 +1183,14 @@ void processTagsAndBaggage(
11771183
// Tags
11781184
TagsPostProcessorFactory.lazyProcessor().processTags(unsafeTags, this, restrictedSpan);
11791185

1180-
String linksTag = DDSpanLink.toTag(restrictedSpan.getLinks());
1181-
if (linksTag != null) {
1182-
unsafeTags.put(SPAN_LINKS, linksTag);
1186+
// Links
1187+
if (injectLinksAsTags) {
1188+
String linksTag = DDSpanLink.toTag(restrictedSpan.getLinks());
1189+
if (linksTag != null) {
1190+
unsafeTags.set(SPAN_LINKS, linksTag);
1191+
}
11831192
}
1193+
11841194
// Baggage
11851195
Map<String, String> baggageItemsWithPropagationTags;
11861196
if (injectBaggageAsTags) {

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpCommonProto.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import datadog.communication.serialization.SimpleUtf8Cache;
1616
import datadog.communication.serialization.StreamingBuffer;
1717
import datadog.trace.api.Config;
18+
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
1819
import datadog.trace.bootstrap.otel.common.OtelInstrumentationScope;
1920
import java.nio.ByteBuffer;
2021
import java.util.List;
@@ -45,6 +46,12 @@ private OtlpCommonProto() {}
4546
? new GenerationalUtf8Cache(Config.get().getTagValueUtf8CacheSize())
4647
: null;
4748

49+
public static void recalibrateCaches() {
50+
if (VALUE_CACHE != null) {
51+
VALUE_CACHE.recalibrate();
52+
}
53+
}
54+
4855
public static int sizeVarInt(int value) {
4956
return 1 + (31 - Integer.numberOfLeadingZeros(value)) / 7;
5057
}
@@ -153,8 +160,13 @@ public static void writeInstrumentationScope(
153160
}
154161

155162
@SuppressWarnings("unchecked")
156-
public static void writeAttribute(StreamingBuffer buf, int type, String key, Object value) {
157-
byte[] keyUtf8 = keyUtf8(key);
163+
public static void writeAttribute(StreamingBuffer buf, int type, CharSequence key, Object value) {
164+
byte[] keyUtf8;
165+
if (key instanceof UTF8BytesString) {
166+
keyUtf8 = ((UTF8BytesString) key).getUtf8Bytes();
167+
} else {
168+
keyUtf8 = keyUtf8(key.toString());
169+
}
158170
switch (type) {
159171
case STRING:
160172
writeStringAttribute(buf, keyUtf8, valueUtf8((String) value));
@@ -163,10 +175,10 @@ public static void writeAttribute(StreamingBuffer buf, int type, String key, Obj
163175
writeBooleanAttribute(buf, keyUtf8, (boolean) value);
164176
break;
165177
case LONG:
166-
writeLongAttribute(buf, keyUtf8, (long) value);
178+
writeLongAttribute(buf, keyUtf8, ((Number) value).longValue());
167179
break;
168180
case DOUBLE:
169-
writeDoubleAttribute(buf, keyUtf8, (double) value);
181+
writeDoubleAttribute(buf, keyUtf8, ((Number) value).doubleValue());
170182
break;
171183
case STRING_ARRAY:
172184
writeStringArrayAttribute(buf, keyUtf8, (List<String>) value);
@@ -175,16 +187,29 @@ public static void writeAttribute(StreamingBuffer buf, int type, String key, Obj
175187
writeBooleanArrayAttribute(buf, keyUtf8, (List<Boolean>) value);
176188
break;
177189
case LONG_ARRAY:
178-
writeLongArrayAttribute(buf, keyUtf8, (List<Long>) value);
190+
writeLongArrayAttribute(buf, keyUtf8, (List<? extends Number>) value);
179191
break;
180192
case DOUBLE_ARRAY:
181-
writeDoubleArrayAttribute(buf, keyUtf8, (List<Double>) value);
193+
writeDoubleArrayAttribute(buf, keyUtf8, (List<? extends Number>) value);
182194
break;
183195
default:
184196
throw new IllegalArgumentException("Unknown attribute type: " + type);
185197
}
186198
}
187199

200+
public static void writeAttribute(
201+
StreamingBuffer buf, UTF8BytesString key, UTF8BytesString value) {
202+
writeStringAttribute(buf, key.getUtf8Bytes(), value.getUtf8Bytes());
203+
}
204+
205+
public static void writeAttribute(StreamingBuffer buf, UTF8BytesString key, String value) {
206+
writeStringAttribute(buf, key.getUtf8Bytes(), valueUtf8(value));
207+
}
208+
209+
public static void writeAttribute(StreamingBuffer buf, UTF8BytesString key, long value) {
210+
writeLongAttribute(buf, key.getUtf8Bytes(), value);
211+
}
212+
188213
private static byte[] keyUtf8(String key) {
189214
return KEY_CACHE != null ? KEY_CACHE.getUtf8(key) : key.getBytes(UTF_8);
190215
}
@@ -301,10 +326,10 @@ private static void writeBooleanArrayAttribute(
301326
}
302327

303328
private static void writeLongArrayAttribute(
304-
StreamingBuffer buf, byte[] keyUtf8, List<Long> values) {
329+
StreamingBuffer buf, byte[] keyUtf8, List<? extends Number> values) {
305330
long[] longValues = new long[values.size()];
306331
for (int i = 0; i < longValues.length; i++) {
307-
longValues[i] = values.get(i); // avoid repeated unboxing later
332+
longValues[i] = values.get(i).longValue(); // avoid repeated unboxing later
308333
}
309334
int arraySize = 0;
310335
for (long longValue : longValues) {
@@ -332,7 +357,7 @@ private static void writeLongArrayAttribute(
332357
}
333358

334359
private static void writeDoubleArrayAttribute(
335-
StreamingBuffer buf, byte[] keyUtf8, List<Double> values) {
360+
StreamingBuffer buf, byte[] keyUtf8, List<? extends Number> values) {
336361
int arraySize = 11 * values.size();
337362
int valueSize = 1 + sizeVarInt(arraySize) + arraySize;
338363
int keyValueSize =
@@ -345,11 +370,11 @@ private static void writeDoubleArrayAttribute(
345370
writeVarInt(buf, valueSize);
346371
writeTag(buf, 5, LEN_WIRE_TYPE);
347372
writeVarInt(buf, arraySize);
348-
for (double value : values) {
373+
for (Number value : values) {
349374
writeTag(buf, 1, LEN_WIRE_TYPE);
350375
buf.put((byte) 9);
351376
writeTag(buf, 4, I64_WIRE_TYPE);
352-
writeI64(buf, value);
377+
writeI64(buf, value.doubleValue());
353378
}
354379
}
355380
}

0 commit comments

Comments
 (0)