From 0dc5a8cbb5be1972166fb89e8ade9e7bf3a40a65 Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Fri, 19 Dec 2025 18:00:58 +0100 Subject: [PATCH 1/7] refactor multiple implementations of W3C trace context building into a dedicated helper --- .../instrumentation/jdbc/JDBCDecorator.java | 19 ++++------- .../jdbc/StatementInstrumentation.java | 3 +- .../mongo/MongoCommentInjector.java | 14 ++------ .../groovy/MongoCommentInjectorTest.groovy | 33 ------------------- .../datadog/trace/api/W3CTraceParent.java | 29 ++++++++++++++++ .../trace/api/W3CTraceParentTest.groovy | 32 ++++++++++++++++++ .../trace/core/propagation/W3CHttpCodec.java | 12 +++---- 7 files changed, 77 insertions(+), 65 deletions(-) create mode 100644 dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java create mode 100644 dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index db38734d252..d079cadd163 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -8,8 +8,8 @@ import static datadog.trace.bootstrap.instrumentation.api.Tags.*; import datadog.trace.api.Config; -import datadog.trace.api.DDSpanId; import datadog.trace.api.DDTraceId; +import datadog.trace.api.W3CTraceParent; import datadog.trace.api.naming.SpanNaming; import datadog.trace.api.telemetry.LogCollector; import datadog.trace.bootstrap.ContextStore; @@ -257,16 +257,6 @@ private AgentSpan withQueryInfo(AgentSpan span, DBQueryInfo info, CharSequence c return span.setTag(Tags.COMPONENT, component); } - public String traceParent(AgentSpan span, int samplingPriority) { - StringBuilder sb = new StringBuilder(55); - sb.append("00-"); - sb.append(span.getTraceId().toHexString()); - sb.append('-'); - sb.append(DDSpanId.toHexStringPadded(span.getSpanId())); - sb.append(samplingPriority > 0 ? "-01" : "-00"); - return sb.toString(); - } - public boolean isOracle(final DBInfo dbInfo) { return "oracle".equals(dbInfo.getType()); } @@ -294,7 +284,9 @@ public void setAction(AgentSpan span, Connection connection) { if (priority == null) { return; } - final String traceContext = DD_INSTRUMENTATION_PREFIX + DECORATE.traceParent(span, priority); + final String traceContext = + DD_INSTRUMENTATION_PREFIX + + W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); connection.setClientInfo("OCSID.ACTION", traceContext); @@ -380,7 +372,8 @@ public void setApplicationName(AgentSpan span, Connection connection) { if (priority == null) { return; } - final String traceParent = DECORATE.traceParent(span, priority); + final String traceParent = + W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); final String traceContext = "_DD_" + traceParent; connection.setClientInfo("ApplicationName", traceContext); diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 0de1423884a..06e16ab051f 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -17,6 +17,7 @@ import datadog.appsec.api.blocking.BlockingException; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.api.W3CTraceParent; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentScope; @@ -119,7 +120,7 @@ public static AgentScope onEnter( Integer priority = span.forceSamplingDecision(); if (priority != null) { if (!isSqlServer) { - traceParent = DECORATE.traceParent(span, priority); + traceParent = W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); } // set the dbm trace injected tag on the span span.setTag(DBM_TRACE_INJECTED, true); diff --git a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java index a9ac9cf04c4..4341cda185b 100644 --- a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java +++ b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java @@ -4,7 +4,7 @@ import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; import datadog.trace.api.Config; -import datadog.trace.api.DDSpanId; +import datadog.trace.api.W3CTraceParent; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.dbm.SharedDBCommenter; import org.bson.BsonArray; @@ -75,7 +75,8 @@ public static String buildComment(AgentSpan dbSpan, String hostname, String dbNa String dbService = dbSpan.getServiceName(); String traceParent = Config.get().getDbmPropagationMode().equals(DBM_PROPAGATION_MODE_FULL) - ? buildTraceParent(dbSpan) + ? W3CTraceParent.build( + dbSpan.getTraceId(), dbSpan.getSpanId(), dbSpan.context().getSamplingPriority()) : null; // Use shared comment builder directly @@ -112,13 +113,4 @@ private static BsonValue mergeComment(BsonValue existingComment, String dbmComme // Incompatible type, preserve existing comment unchanged return existingComment; } - - static String buildTraceParent(AgentSpan span) { - // W3C traceparent format: version-traceId-spanId-flags - return "00-" // version - + span.getTraceId().toHexString() // traceId - + '-' - + DDSpanId.toHexStringPadded(span.getSpanId()) // spanId - + (span.context().getSamplingPriority() > 0 ? "-01" : "-00"); - } } diff --git a/dd-java-agent/instrumentation/mongo/common/src/test/groovy/MongoCommentInjectorTest.groovy b/dd-java-agent/instrumentation/mongo/common/src/test/groovy/MongoCommentInjectorTest.groovy index e3643609905..e562cfe6b74 100644 --- a/dd-java-agent/instrumentation/mongo/common/src/test/groovy/MongoCommentInjectorTest.groovy +++ b/dd-java-agent/instrumentation/mongo/common/src/test/groovy/MongoCommentInjectorTest.groovy @@ -1,6 +1,5 @@ import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.api.config.TraceInstrumentationConfig -import datadog.trace.api.sampling.PrioritySampling import datadog.trace.instrumentation.mongo.MongoCommentInjector import org.bson.BsonDocument import org.bson.BsonString @@ -18,38 +17,6 @@ abstract class BaseMongoCommentInjectorTest extends InstrumentationSpecification } class MongoCommentInjectorTest extends BaseMongoCommentInjectorTest { - def "buildTraceParent with sampled flag (SAMPLER_KEEP)"() { - setup: - def span = TEST_TRACER.buildSpan("test-op").start() - span.setSamplingPriority(PrioritySampling.SAMPLER_KEEP, 0) - - when: - String traceParent = MongoCommentInjector.buildTraceParent(span) - - then: - traceParent != null - traceParent ==~ /00-[0-9a-f]{32}-[0-9a-f]{16}-01/ - - cleanup: - span?.finish() - } - - def "buildTraceParent with not sampled flag (SAMPLER_DROP)"() { - setup: - def span = TEST_TRACER.buildSpan("test-op").start() - span.setSamplingPriority(PrioritySampling.SAMPLER_DROP, 0) - - when: - String traceParent = MongoCommentInjector.buildTraceParent(span) - - then: - traceParent != null - traceParent ==~ /00-[0-9a-f]{32}-[0-9a-f]{16}-00/ - - cleanup: - span?.finish() - } - def "injectComment returns null when event is null"() { when: BsonDocument result = MongoCommentInjector.injectComment("test-comment", null) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java b/dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java new file mode 100644 index 00000000000..6896c68e4c0 --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java @@ -0,0 +1,29 @@ +package datadog.trace.api; + +/** + * Utility class for building W3C traceparent headers. + * + * @see W3C Trace Context + */ +public final class W3CTraceParent { + + private W3CTraceParent() {} + + /** + * Builds a W3C traceparent header value from the given trace context components. + * + *

Format: {@code ---} + * + * @param traceId the trace id + * @param spanId the span id + * @param samplingPriority the sampling priority (positive values result in sampled flag set) + * @return the W3C traceparent header value + */ + public static String build(DDTraceId traceId, long spanId, int samplingPriority) { + return "00-" + + traceId.toHexString() + + '-' + + DDSpanId.toHexStringPadded(spanId) + + (samplingPriority > 0 ? "-01" : "-00"); + } +} diff --git a/dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy b/dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy new file mode 100644 index 00000000000..f09efe4434f --- /dev/null +++ b/dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy @@ -0,0 +1,32 @@ +package datadog.trace.api + +import datadog.trace.test.util.DDSpecification + +class W3CTraceParentTest extends DDSpecification { + + def "build produces correct format with samplingPriority=#samplingPriority"() { + when: + def result = W3CTraceParent.build(traceId, spanId, samplingPriority) + + then: + result == expected + + where: + traceId | spanId | samplingPriority | expected + DDTraceId.from(1) | 2 | 1 | "00-00000000000000000000000000000001-0000000000000002-01" + DDTraceId.from(1) | 2 | 0 | "00-00000000000000000000000000000001-0000000000000002-00" + DDTraceId.from(1) | 2 | -1 | "00-00000000000000000000000000000001-0000000000000002-00" + DDTraceId.from(1) | 2 | 2 | "00-00000000000000000000000000000001-0000000000000002-01" + DDTraceId.fromHex("0af7651916cd43dd8448eb211c80319c") | 0x00f067aa0ba902b7L | 1 | "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" + DDTraceId.from(Long.MAX_VALUE) | Long.MAX_VALUE | 1 | "00-00000000000000007fffffffffffffff-7fffffffffffffff-01" + } + + def "build matches W3C traceparent format"() { + when: + def result = W3CTraceParent.build(DDTraceId.from(123456789L), 987654321L, 1) + + then: + // W3C format: version-traceId(32 hex)-spanId(16 hex)-flags(2 hex) + result ==~ /00-[0-9a-f]{32}-[0-9a-f]{16}-(00|01)/ + } +} diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java index c201047fd01..5238bb1fd55 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java @@ -16,6 +16,7 @@ import datadog.trace.api.DDTraceId; import datadog.trace.api.TraceConfig; import datadog.trace.api.TracePropagationStyle; +import datadog.trace.api.W3CTraceParent; import datadog.trace.api.internal.util.LongStringUtils; import datadog.trace.api.sampling.PrioritySampling; import datadog.trace.api.sampling.SamplingMechanism; @@ -70,13 +71,10 @@ public void inject( } private void injectTraceParent(DDSpanContext context, C carrier, CarrierSetter setter) { - StringBuilder sb = new StringBuilder(TRACE_PARENT_LENGTH); - sb.append("00-"); - sb.append(context.getTraceId().toHexString()); - sb.append('-'); - sb.append(DDSpanId.toHexStringPadded(context.getSpanId())); - sb.append(context.getSamplingPriority() > 0 ? "-01" : "-00"); - setter.set(carrier, TRACE_PARENT_KEY, sb.toString()); + String traceparent = + W3CTraceParent.build( + context.getTraceId(), context.getSpanId(), context.getSamplingPriority()); + setter.set(carrier, TRACE_PARENT_KEY, traceparent); } private void injectTraceState(DDSpanContext context, C carrier, CarrierSetter setter) { From 0d19785ed80c8a4c1fcdfb1ff95237d34afb5043 Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 11:18:22 +0100 Subject: [PATCH 2/7] move W3CTraceParent utility to core package instead of public API --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 2 +- .../instrumentation/jdbc/StatementInstrumentation.java | 2 +- .../trace/instrumentation/mongo/MongoCommentInjector.java | 2 +- .../java/datadog/trace/core/propagation/W3CHttpCodec.java | 1 - .../datadog/trace/core/propagation}/W3CTraceParent.java | 5 ++++- .../trace/core/propagation}/W3CTraceParentTest.groovy | 7 ++++--- 6 files changed, 11 insertions(+), 8 deletions(-) rename {dd-trace-api/src/main/java/datadog/trace/api => dd-trace-core/src/main/java/datadog/trace/core/propagation}/W3CTraceParent.java (88%) rename {dd-trace-api/src/test/groovy/datadog/trace/api => dd-trace-core/src/test/groovy/datadog/trace/core/propagation}/W3CTraceParentTest.groovy (86%) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index d079cadd163..66efe0facae 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -9,7 +9,6 @@ import datadog.trace.api.Config; import datadog.trace.api.DDTraceId; -import datadog.trace.api.W3CTraceParent; import datadog.trace.api.naming.SpanNaming; import datadog.trace.api.telemetry.LogCollector; import datadog.trace.bootstrap.ContextStore; @@ -23,6 +22,7 @@ import datadog.trace.bootstrap.instrumentation.jdbc.DBInfo; import datadog.trace.bootstrap.instrumentation.jdbc.DBQueryInfo; import datadog.trace.bootstrap.instrumentation.jdbc.JDBCConnectionUrlParser; +import datadog.trace.core.propagation.W3CTraceParent; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.sql.Connection; diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 06e16ab051f..30fe7ca9d6d 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -17,13 +17,13 @@ import datadog.appsec.api.blocking.BlockingException; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.W3CTraceParent; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import datadog.trace.bootstrap.instrumentation.jdbc.DBInfo; +import datadog.trace.core.propagation.W3CTraceParent; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; diff --git a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java index 4341cda185b..2d4ad152035 100644 --- a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java +++ b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java @@ -4,9 +4,9 @@ import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; import datadog.trace.api.Config; -import datadog.trace.api.W3CTraceParent; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.dbm.SharedDBCommenter; +import datadog.trace.core.propagation.W3CTraceParent; import org.bson.BsonArray; import org.bson.BsonDocument; import org.bson.BsonString; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java index 5238bb1fd55..361e4086319 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java @@ -16,7 +16,6 @@ import datadog.trace.api.DDTraceId; import datadog.trace.api.TraceConfig; import datadog.trace.api.TracePropagationStyle; -import datadog.trace.api.W3CTraceParent; import datadog.trace.api.internal.util.LongStringUtils; import datadog.trace.api.sampling.PrioritySampling; import datadog.trace.api.sampling.SamplingMechanism; diff --git a/dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java similarity index 88% rename from dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java rename to dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java index 6896c68e4c0..a073eb754cf 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/W3CTraceParent.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java @@ -1,4 +1,7 @@ -package datadog.trace.api; +package datadog.trace.core.propagation; + +import datadog.trace.api.DDSpanId; +import datadog.trace.api.DDTraceId; /** * Utility class for building W3C traceparent headers. diff --git a/dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy similarity index 86% rename from dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy rename to dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy index f09efe4434f..b04bb5cd909 100644 --- a/dd-trace-api/src/test/groovy/datadog/trace/api/W3CTraceParentTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy @@ -1,12 +1,13 @@ -package datadog.trace.api +package datadog.trace.core.propagation +import datadog.trace.api.DDTraceId import datadog.trace.test.util.DDSpecification class W3CTraceParentTest extends DDSpecification { def "build produces correct format with samplingPriority=#samplingPriority"() { when: - def result = W3CTraceParent.build(traceId, spanId, samplingPriority) + def result = W3CTraceParent.from(traceId, spanId, samplingPriority) then: result == expected @@ -23,7 +24,7 @@ class W3CTraceParentTest extends DDSpecification { def "build matches W3C traceparent format"() { when: - def result = W3CTraceParent.build(DDTraceId.from(123456789L), 987654321L, 1) + def result = W3CTraceParent.from(DDTraceId.from(123456789L), 987654321L, 1) then: // W3C format: version-traceId(32 hex)-spanId(16 hex)-flags(2 hex) From bab0627173a8cb77af1d3d09130317f4cfbccde7 Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 11:19:10 +0100 Subject: [PATCH 3/7] create overloads to make W3CTraceParent util easier to use --- .../trace/instrumentation/jdbc/JDBCDecorator.java | 7 ++----- .../jdbc/StatementInstrumentation.java | 2 +- .../instrumentation/mongo/MongoCommentInjector.java | 3 +-- .../trace/core/propagation/W3CHttpCodec.java | 4 +--- .../trace/core/propagation/W3CTraceParent.java | 13 ++++++++++++- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 66efe0facae..0a1630572ea 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -284,9 +284,7 @@ public void setAction(AgentSpan span, Connection connection) { if (priority == null) { return; } - final String traceContext = - DD_INSTRUMENTATION_PREFIX - + W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); + final String traceContext = DD_INSTRUMENTATION_PREFIX + W3CTraceParent.from(span); connection.setClientInfo("OCSID.ACTION", traceContext); @@ -372,8 +370,7 @@ public void setApplicationName(AgentSpan span, Connection connection) { if (priority == null) { return; } - final String traceParent = - W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); + final String traceParent = W3CTraceParent.from(span); final String traceContext = "_DD_" + traceParent; connection.setClientInfo("ApplicationName", traceContext); diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 30fe7ca9d6d..7b0d4e99262 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -120,7 +120,7 @@ public static AgentScope onEnter( Integer priority = span.forceSamplingDecision(); if (priority != null) { if (!isSqlServer) { - traceParent = W3CTraceParent.build(span.getTraceId(), span.getSpanId(), priority); + traceParent = W3CTraceParent.from(span); } // set the dbm trace injected tag on the span span.setTag(DBM_TRACE_INJECTED, true); diff --git a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java index 2d4ad152035..4028a059795 100644 --- a/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java +++ b/dd-java-agent/instrumentation/mongo/common/src/main/java/datadog/trace/instrumentation/mongo/MongoCommentInjector.java @@ -75,8 +75,7 @@ public static String buildComment(AgentSpan dbSpan, String hostname, String dbNa String dbService = dbSpan.getServiceName(); String traceParent = Config.get().getDbmPropagationMode().equals(DBM_PROPAGATION_MODE_FULL) - ? W3CTraceParent.build( - dbSpan.getTraceId(), dbSpan.getSpanId(), dbSpan.context().getSamplingPriority()) + ? W3CTraceParent.from(dbSpan) : null; // Use shared comment builder directly diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java index 361e4086319..1e1d442575e 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CHttpCodec.java @@ -70,9 +70,7 @@ public void inject( } private void injectTraceParent(DDSpanContext context, C carrier, CarrierSetter setter) { - String traceparent = - W3CTraceParent.build( - context.getTraceId(), context.getSpanId(), context.getSamplingPriority()); + String traceparent = W3CTraceParent.from(context); setter.set(carrier, TRACE_PARENT_KEY, traceparent); } diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java index a073eb754cf..d34c024c270 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java @@ -2,6 +2,8 @@ import datadog.trace.api.DDSpanId; import datadog.trace.api.DDTraceId; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.core.DDSpanContext; /** * Utility class for building W3C traceparent headers. @@ -22,11 +24,20 @@ private W3CTraceParent() {} * @param samplingPriority the sampling priority (positive values result in sampled flag set) * @return the W3C traceparent header value */ - public static String build(DDTraceId traceId, long spanId, int samplingPriority) { + public static String from(DDTraceId traceId, long spanId, int samplingPriority) { return "00-" + traceId.toHexString() + '-' + DDSpanId.toHexStringPadded(spanId) + (samplingPriority > 0 ? "-01" : "-00"); } + + public static String from(AgentSpan span) { + return from(span.getTraceId(), span.getSpanId(), span.context().getSamplingPriority()); + } + + public static String from(DDSpanContext spanContext) { + return from( + spanContext.getTraceId(), spanContext.getSpanId(), spanContext.getSamplingPriority()); + } } From 6fc094a3da9379b6b61bb565bf8c67efb1cd79a9 Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 11:52:25 +0100 Subject: [PATCH 4/7] fix missing helper class definition in mongodb instrumentation --- .../mongo/DefaultServerConnection36Instrumentation.java | 1 + .../mongo/DefaultServerConnection38Instrumentation.java | 1 + 2 files changed, 2 insertions(+) diff --git a/dd-java-agent/instrumentation/mongo/driver-3.6/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection36Instrumentation.java b/dd-java-agent/instrumentation/mongo/driver-3.6/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection36Instrumentation.java index 894eac74b2b..bdf93a0febe 100644 --- a/dd-java-agent/instrumentation/mongo/driver-3.6/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection36Instrumentation.java +++ b/dd-java-agent/instrumentation/mongo/driver-3.6/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection36Instrumentation.java @@ -32,6 +32,7 @@ public String instrumentedType() { @Override public String[] helperClassNames() { return new String[] { + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".BsonScrubber", packageName + ".MongoCommentInjector", packageName + ".MongoDecorator", diff --git a/dd-java-agent/instrumentation/mongo/driver-3.8/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection38Instrumentation.java b/dd-java-agent/instrumentation/mongo/driver-3.8/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection38Instrumentation.java index 14453fa8204..7512e30173e 100644 --- a/dd-java-agent/instrumentation/mongo/driver-3.8/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection38Instrumentation.java +++ b/dd-java-agent/instrumentation/mongo/driver-3.8/src/main/java/datadog/trace/instrumentation/mongo/DefaultServerConnection38Instrumentation.java @@ -33,6 +33,7 @@ public String instrumentedType() { public String[] helperClassNames() { return new String[] { "datadog.trace.bootstrap.instrumentation.dbm.SharedDBCommenter", + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".MongoDecorator", packageName + ".MongoCommentInjector", packageName + ".BsonScrubber", From 4a4b35f07485811d698f9f47eff4ea96de616f08 Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 13:34:18 +0100 Subject: [PATCH 5/7] fix missing helper class definition in jdbc instrumentations --- .../instrumentation/jdbc/AbstractConnectionInstrumentation.java | 2 +- .../jdbc/AbstractPreparedStatementInstrumentation.java | 2 +- .../jdbc/DBMCompatibleConnectionInstrumentation.java | 1 + .../trace/instrumentation/jdbc/DriverInstrumentation.java | 2 +- .../trace/instrumentation/jdbc/StatementInstrumentation.java | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractConnectionInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractConnectionInstrumentation.java index a19e2cd345d..1baf5a38499 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractConnectionInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractConnectionInstrumentation.java @@ -33,7 +33,7 @@ public Map contextStore() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".JDBCDecorator", + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".JDBCDecorator", }; } diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java index 016e1ed8d88..a8e94fae86a 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java @@ -40,7 +40,7 @@ public AbstractPreparedStatementInstrumentation( @Override public String[] helperClassNames() { return new String[] { - packageName + ".JDBCDecorator", + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".JDBCDecorator", }; } diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DBMCompatibleConnectionInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DBMCompatibleConnectionInstrumentation.java index 1b52f827bda..4d0de9e3b27 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DBMCompatibleConnectionInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DBMCompatibleConnectionInstrumentation.java @@ -78,6 +78,7 @@ public DBMCompatibleConnectionInstrumentation() { @Override public String[] helperClassNames() { return new String[] { + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".JDBCDecorator", packageName + ".SQLCommenter", "datadog.trace.bootstrap.instrumentation.dbm.SharedDBCommenter", diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DriverInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DriverInstrumentation.java index c5c266ed312..27fc191fbed 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DriverInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DriverInstrumentation.java @@ -49,7 +49,7 @@ public Map contextStore() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".JDBCDecorator", + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".JDBCDecorator", }; } diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 7b0d4e99262..5ff309de3cd 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -60,6 +60,7 @@ public Map contextStore() { @Override public String[] helperClassNames() { return new String[] { + "datadog.trace.core.propagation.W3CTraceParent", packageName + ".JDBCDecorator", packageName + ".SQLCommenter", "datadog.trace.bootstrap.instrumentation.dbm.SharedDBCommenter", From 8d93099fd5323b768795e9ad610f25649c623fea Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 15:39:37 +0100 Subject: [PATCH 6/7] replace string concatenation by string builder --- .../trace/core/propagation/W3CTraceParent.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java index d34c024c270..8c3bf016f16 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java @@ -12,6 +12,8 @@ */ public final class W3CTraceParent { + private static final int TRACE_PARENT_LENGTH = 55; + private W3CTraceParent() {} /** @@ -25,11 +27,14 @@ private W3CTraceParent() {} * @return the W3C traceparent header value */ public static String from(DDTraceId traceId, long spanId, int samplingPriority) { - return "00-" - + traceId.toHexString() - + '-' - + DDSpanId.toHexStringPadded(spanId) - + (samplingPriority > 0 ? "-01" : "-00"); + StringBuilder sb = new StringBuilder(TRACE_PARENT_LENGTH); + sb.append("00-"); + sb.append(traceId.toHexString()); + sb.append('-'); + sb.append(DDSpanId.toHexStringPadded(spanId)); + sb.append(samplingPriority > 0 ? "-01" : "-00"); + + return sb.toString(); } public static String from(AgentSpan span) { From 625a4988c62d0dc1569f53f730e4bce3701ac3ba Mon Sep 17 00:00:00 2001 From: Naji Astier Date: Mon, 22 Dec 2025 15:53:33 +0100 Subject: [PATCH 7/7] remove sampling priority argument from the trace parent util --- .../core/propagation/W3CTraceParent.java | 10 +++++----- .../propagation/W3CTraceParentTest.groovy | 19 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java index 8c3bf016f16..4a1b6eb822c 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/W3CTraceParent.java @@ -23,26 +23,26 @@ private W3CTraceParent() {} * * @param traceId the trace id * @param spanId the span id - * @param samplingPriority the sampling priority (positive values result in sampled flag set) + * @param isSampled whether the trace was sampled or not * @return the W3C traceparent header value */ - public static String from(DDTraceId traceId, long spanId, int samplingPriority) { + public static String from(DDTraceId traceId, long spanId, boolean isSampled) { StringBuilder sb = new StringBuilder(TRACE_PARENT_LENGTH); sb.append("00-"); sb.append(traceId.toHexString()); sb.append('-'); sb.append(DDSpanId.toHexStringPadded(spanId)); - sb.append(samplingPriority > 0 ? "-01" : "-00"); + sb.append(isSampled ? "-01" : "-00"); return sb.toString(); } public static String from(AgentSpan span) { - return from(span.getTraceId(), span.getSpanId(), span.context().getSamplingPriority()); + return from(span.getTraceId(), span.getSpanId(), span.context().getSamplingPriority() > 0); } public static String from(DDSpanContext spanContext) { return from( - spanContext.getTraceId(), spanContext.getSpanId(), spanContext.getSamplingPriority()); + spanContext.getTraceId(), spanContext.getSpanId(), spanContext.getSamplingPriority() > 0); } } diff --git a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy index b04bb5cd909..1e9ae585903 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/core/propagation/W3CTraceParentTest.groovy @@ -5,26 +5,25 @@ import datadog.trace.test.util.DDSpecification class W3CTraceParentTest extends DDSpecification { - def "build produces correct format with samplingPriority=#samplingPriority"() { + def "build produces correct format with isSampled=#isSampled"() { when: - def result = W3CTraceParent.from(traceId, spanId, samplingPriority) + def result = W3CTraceParent.from(traceId, spanId, isSampled) then: result == expected where: - traceId | spanId | samplingPriority | expected - DDTraceId.from(1) | 2 | 1 | "00-00000000000000000000000000000001-0000000000000002-01" - DDTraceId.from(1) | 2 | 0 | "00-00000000000000000000000000000001-0000000000000002-00" - DDTraceId.from(1) | 2 | -1 | "00-00000000000000000000000000000001-0000000000000002-00" - DDTraceId.from(1) | 2 | 2 | "00-00000000000000000000000000000001-0000000000000002-01" - DDTraceId.fromHex("0af7651916cd43dd8448eb211c80319c") | 0x00f067aa0ba902b7L | 1 | "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" - DDTraceId.from(Long.MAX_VALUE) | Long.MAX_VALUE | 1 | "00-00000000000000007fffffffffffffff-7fffffffffffffff-01" + traceId | spanId | isSampled | expected + DDTraceId.from(1) | 2 | true | "00-00000000000000000000000000000001-0000000000000002-01" + DDTraceId.from(1) | 2 | false | "00-00000000000000000000000000000001-0000000000000002-00" + DDTraceId.from(1) | 2 | true | "00-00000000000000000000000000000001-0000000000000002-01" + DDTraceId.fromHex("0af7651916cd43dd8448eb211c80319c") | 0x00f067aa0ba902b7L | true | "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" + DDTraceId.from(Long.MAX_VALUE) | Long.MAX_VALUE | true | "00-00000000000000007fffffffffffffff-7fffffffffffffff-01" } def "build matches W3C traceparent format"() { when: - def result = W3CTraceParent.from(DDTraceId.from(123456789L), 987654321L, 1) + def result = W3CTraceParent.from(DDTraceId.from(123456789L), 987654321L, true) then: // W3C format: version-traceId(32 hex)-spanId(16 hex)-flags(2 hex)