Skip to content

Commit 0e5b9e7

Browse files
dougqhclaude
andcommitted
Parse the traceparent trace id once on the full extraction path
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent e96e97d commit 0e5b9e7

2 files changed

Lines changed: 30 additions & 17 deletions

File tree

‎dd-trace-core/src/main/java/datadog/trace/core/propagation/HttpCodec.java‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,6 @@ public void forEachKey(ExtractionCache<?> carrier, AgentPropagation.KeyClassifie
366366
}
367367
}
368368

369-
/**
370-
* Checks if trace identifier matches, even if they are not encoded using the same size (64-bit vs
371-
* 128-bit).
372-
*
373-
* @param a A trace identifier to check.
374-
* @param b Another trace identifier to check.
375-
* @return {@code true} if the trace identifiers matches, {@code false} otherwise.
376-
*/
377369
/** {@link #traceIdMatch(DDTraceId, DDTraceId)} against a 128-bit id given by its parts. */
378370
private static boolean traceIdMatch(DDTraceId a, long bHigh, long bLow) {
379371
if (a instanceof DD128bTraceId) {
@@ -382,6 +374,14 @@ private static boolean traceIdMatch(DDTraceId a, long bHigh, long bLow) {
382374
return a.toLong() == bLow;
383375
}
384376

377+
/**
378+
* Checks if trace identifier matches, even if they are not encoded using the same size (64-bit vs
379+
* 128-bit).
380+
*
381+
* @param a A trace identifier to check.
382+
* @param b Another trace identifier to check.
383+
* @return {@code true} if the trace identifiers matches, {@code false} otherwise.
384+
*/
385385
private static boolean traceIdMatch(DDTraceId a, DDTraceId b) {
386386
if (a instanceof DD128bTraceId && b instanceof DD128bTraceId
387387
|| a instanceof DD64bTraceId && b instanceof DD64bTraceId) {

‎dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,14 @@ protected TagContext build() {
343343
private long traceIdLow;
344344

345345
void parseTraceParentHeader(String tp) {
346-
parseTraceParent(tp);
347-
this.traceId = DD128bTraceId.fromHex(tp, TRACE_PARENT_TID_START, 32, true);
346+
parseTraceParent(tp, true);
348347
}
349348

350-
/** Validates the traceparent and reads its parts, except for building the trace id. */
351-
private void parseTraceParent(String tp) {
349+
/**
350+
* Validates the traceparent and reads its parts. The trace id is built only if {@code
351+
* buildTraceId}; its high and low order bits are read either way.
352+
*/
353+
private void parseTraceParent(String tp, boolean buildTraceId) {
352354
int length = tp == null ? 0 : tp.length();
353355
if (length < TRACE_PARENT_LENGTH) {
354356
throw new IllegalStateException("The length of traceparent '" + tp + "' is too short");
@@ -359,15 +361,26 @@ private void parseTraceParent(String tp) {
359361
} else if (version == 0 && length > TRACE_PARENT_LENGTH) {
360362
throw new IllegalStateException("The length of traceparent '" + tp + "' is too long");
361363
}
362-
// as DD128bTraceId.fromHex(tp, TRACE_PARENT_TID_START, 32, true) parses them
363-
this.traceIdHigh = LongStringUtils.parseUnsignedLongHex(tp, TRACE_PARENT_TID_START, 16, true);
364-
this.traceIdLow =
365-
LongStringUtils.parseUnsignedLongHex(tp, TRACE_PARENT_TID_START + 16, 16, true);
364+
DD128bTraceId traceId = null;
365+
if (buildTraceId) {
366+
traceId = DD128bTraceId.fromHex(tp, TRACE_PARENT_TID_START, 32, true);
367+
this.traceIdHigh = traceId.toHighOrderLong();
368+
this.traceIdLow = traceId.toLong();
369+
} else {
370+
// as DD128bTraceId.fromHex(tp, TRACE_PARENT_TID_START, 32, true) parses them
371+
this.traceIdHigh =
372+
LongStringUtils.parseUnsignedLongHex(tp, TRACE_PARENT_TID_START, 16, true);
373+
this.traceIdLow =
374+
LongStringUtils.parseUnsignedLongHex(tp, TRACE_PARENT_TID_START + 16, 16, true);
375+
}
366376
if (traceIdLow == 0) {
367377
throw new IllegalStateException(
368378
"Illegal all zero 64 bit trace id "
369379
+ tp.substring(TRACE_PARENT_TID_START, TRACE_PARENT_TID_END));
370380
}
381+
if (traceId != null) {
382+
this.traceId = traceId;
383+
}
371384
this.spanId = DDSpanId.fromHex(tp, TRACE_PARENT_SID_START, 16, true);
372385
if (this.spanId == 0) {
373386
throw new IllegalStateException(
@@ -400,7 +413,7 @@ TraceContextMerge buildForMerge() {
400413
"Found no traceparent header but tracestate header '" + tracestateHeader + "'");
401414
}
402415
// the trace id only needs to be compared, so it's kept as its parts
403-
parseTraceParent(traceparentHeader);
416+
parseTraceParent(traceparentHeader, false);
404417
tracestate = W3CTracestate.parse(tracestateHeader);
405418
} catch (RuntimeException e) {
406419
log.debug("Exception when building context", e);

0 commit comments

Comments
 (0)