From 0384afd3aadf431045708356183afdb02eec2486 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 3 Sep 2025 18:24:38 +0200 Subject: [PATCH 1/2] Enable process level tags for java 21 applications --- .../src/main/java/datadog/trace/api/Config.java | 3 ++- .../datadog/trace/api/ProcessTagsForkedTest.groovy | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index 074edf0c62b..fb943ab3685 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -1508,7 +1508,8 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins removeIntegrationServiceNamesEnabled = configProvider.getBoolean(TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED, false); experimentalPropagateProcessTagsEnabled = - configProvider.getBoolean(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, false); + configProvider.getBoolean( + EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, JavaVirtualMachine.isJavaVersion(21)); peerServiceMapping = configProvider.getMergedMap(TRACE_PEER_SERVICE_MAPPING); diff --git a/internal-api/src/test/groovy/datadog/trace/api/ProcessTagsForkedTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/ProcessTagsForkedTest.groovy index 34d530b3fd8..52b3ffd2f3a 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/ProcessTagsForkedTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/ProcessTagsForkedTest.groovy @@ -1,5 +1,6 @@ package datadog.trace.api +import datadog.environment.JavaVirtualMachine import datadog.trace.api.env.CapturedEnvironment import datadog.trace.test.util.DDSpecification @@ -88,19 +89,20 @@ class ProcessTagsForkedTest extends DDSpecification { null | "server1" | "^((?!cluster.name|server.name|server.type).)*\$" } - def 'should not calculate process tags by default'() { + def 'should not calculate process tags by default except for java 21'() { + final boolean shouldBeEnabled = JavaVirtualMachine.isJavaVersion(21) when: ProcessTags.reset() def processTags = ProcessTags.tagsForSerialization then: - assert !ProcessTags.enabled - assert processTags == null + assert ProcessTags.enabled == shouldBeEnabled + assert (processTags != null) == shouldBeEnabled when: ProcessTags.addTag("test", "value") then: - assert ProcessTags.tagsForSerialization == null - assert ProcessTags.tagsAsStringList == null - assert ProcessTags.tagsAsUTF8ByteStringList == null + assert (ProcessTags.tagsForSerialization != null) == shouldBeEnabled + assert (ProcessTags.tagsAsStringList != null) == shouldBeEnabled + assert (ProcessTags.tagsAsUTF8ByteStringList != null) == shouldBeEnabled } def 'should lazily recalculate when a tag is added'() { From f5b5f3a016d43b247447727704a9f096a4ab43fe Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 3 Sep 2025 19:26:26 +0200 Subject: [PATCH 2/2] Adapt tests --- .../src/latestDepTest/groovy/TomcatServer.groovy | 1 + .../datadog/smoketest/TracerDebuggerIntegrationTest.java | 4 ++++ .../datadog/trace/common/writer/DDAgentApiTest.groovy | 8 ++++++-- .../writer/ddagent/TraceMapperV05PayloadTest.groovy | 7 +++++++ .../datadog/remoteconfig/PollerRequestFactoryTest.groovy | 4 ++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/tomcat-5.5/src/latestDepTest/groovy/TomcatServer.groovy b/dd-java-agent/instrumentation/tomcat-5.5/src/latestDepTest/groovy/TomcatServer.groovy index a8f318d64dd..1432a035609 100644 --- a/dd-java-agent/instrumentation/tomcat-5.5/src/latestDepTest/groovy/TomcatServer.groovy +++ b/dd-java-agent/instrumentation/tomcat-5.5/src/latestDepTest/groovy/TomcatServer.groovy @@ -65,6 +65,7 @@ class TomcatServer implements WebsocketServer { port = server.service.findConnectors()[0].localPort assert port > 0 if (Config.get().isExperimentalPropagateProcessTagsEnabled()) { + server.getEngine().setName("tomcat") def serverName = TraceUtils.normalizeTag(server.getEngine().getName()) assert ProcessTags.getTagsAsStringList().containsAll(["server.type:tomcat", "server.name:" + serverName]) } else { diff --git a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java index ea198200ac3..fdd7c813e36 100644 --- a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java +++ b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java @@ -11,6 +11,7 @@ import com.datadog.debugger.probe.LogProbe; import com.datadog.debugger.sink.Snapshot; import com.squareup.moshi.JsonAdapter; +import datadog.environment.JavaVirtualMachine; import datadog.trace.agent.test.utils.PortUtils; import datadog.trace.bootstrap.debugger.MethodLocation; import datadog.trace.bootstrap.debugger.ProbeId; @@ -184,6 +185,9 @@ private JsonSnapshotSerializer.IntakeRequest doTestTracer( ProcessBuilder processBuilder = createProcessBuilder(logFilePath, "--server.port=" + httpPort); if (enableProcessTags) { processBuilder.environment().put("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED", "true"); + } else if (JavaVirtualMachine.isJavaVersion(21)) { + // disable explicitly since enable by default on 21 + processBuilder.environment().put("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED", "false"); } targetProcess = processBuilder.start(); // assert in logs app started diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/writer/DDAgentApiTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/writer/DDAgentApiTest.groovy index 76e7622fe51..a59846a65db 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/common/writer/DDAgentApiTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/common/writer/DDAgentApiTest.groovy @@ -8,6 +8,8 @@ import datadog.communication.monitor.Monitoring import datadog.communication.serialization.ByteBufferConsumer import datadog.communication.serialization.FlushingBuffer import datadog.communication.serialization.msgpack.MsgPackWriter +import datadog.trace.api.Config +import datadog.trace.api.ProcessTags import datadog.trace.api.StatsDClient import datadog.trace.bootstrap.instrumentation.api.InstrumentationTags import datadog.trace.common.sampling.RateByServiceTraceSampler @@ -137,7 +139,8 @@ class DDAgentApiTest extends DDCoreSpecification { [[buildSpan(1L, "service.name", "my-service", PropagationTags.factory().fromHeaderValue(PropagationTags.HeaderType.DATADOG, "_dd.p.usr=123"))]] | [[new TreeMap<>([ "duration" : 10, "error" : 0, - "meta" : ["thread.name": Thread.currentThread().getName(), "_dd.p.usr": "123", "_dd.p.dm": "-1"], + "meta" : ["thread.name": Thread.currentThread().getName(), "_dd.p.usr": "123", "_dd.p.dm": "-1"] + + (Config.get().isExperimentalPropagateProcessTagsEnabled() ? ["_dd.tags.process" : ProcessTags.getTagsForSerialization().toString()] : []), "metrics" : [ (DDSpanContext.PRIORITY_SAMPLING_KEY) : 1, (InstrumentationTags.DD_TOP_LEVEL as String) : 1, @@ -157,7 +160,8 @@ class DDAgentApiTest extends DDCoreSpecification { [[buildSpan(100L, "resource.name", "my-resource", PropagationTags.factory().fromHeaderValue(PropagationTags.HeaderType.DATADOG, "_dd.p.usr=123"))]] | [[new TreeMap<>([ "duration" : 10, "error" : 0, - "meta" : ["thread.name": Thread.currentThread().getName(), "_dd.p.usr": "123", "_dd.p.dm": "-1"], + "meta" : ["thread.name": Thread.currentThread().getName(), "_dd.p.usr": "123", "_dd.p.dm": "-1"] + + (Config.get().isExperimentalPropagateProcessTagsEnabled() ? ["_dd.tags.process" : ProcessTags.getTagsForSerialization().toString()] : []), "metrics" : [ (DDSpanContext.PRIORITY_SAMPLING_KEY) : 1, (InstrumentationTags.DD_TOP_LEVEL as String) : 1, diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/writer/ddagent/TraceMapperV05PayloadTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/writer/ddagent/TraceMapperV05PayloadTest.groovy index c534b4412a5..2ca7322a9b8 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/common/writer/ddagent/TraceMapperV05PayloadTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/common/writer/ddagent/TraceMapperV05PayloadTest.groovy @@ -36,6 +36,10 @@ class TraceMapperV05PayloadTest extends DDSpecification { def "body overflow causes a flush"() { setup: + // disable process tags since they are only on the first span of the chunk otherwise the calculation woes + def hadProcessTags = Config.get().isExperimentalPropagateProcessTagsEnabled() + injectSysConfig(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, "false") + ProcessTags.reset() // 4x 36 ASCII characters and 2 bytes of msgpack string prefix int dictionarySpacePerTrace = 4 * (36 + 2) // enough space for two traces with distinct string values, plus the header @@ -78,6 +82,9 @@ class TraceMapperV05PayloadTest extends DDSpecification { } then: verifier.verifyTracesConsumed() + cleanup: + injectSysConfig(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, Boolean.toString(hadProcessTags)) + ProcessTags.reset() } def "test dictionary compressed traces written correctly"() { diff --git a/remote-config/remote-config-core/src/test/groovy/datadog/remoteconfig/PollerRequestFactoryTest.groovy b/remote-config/remote-config-core/src/test/groovy/datadog/remoteconfig/PollerRequestFactoryTest.groovy index 601beadd9e4..7a01e446f32 100644 --- a/remote-config/remote-config-core/src/test/groovy/datadog/remoteconfig/PollerRequestFactoryTest.groovy +++ b/remote-config/remote-config-core/src/test/groovy/datadog/remoteconfig/PollerRequestFactoryTest.groovy @@ -1,6 +1,7 @@ package datadog.remoteconfig import com.squareup.moshi.Moshi +import datadog.environment.JavaVirtualMachine import datadog.remoteconfig.tuf.RemoteConfigRequest import datadog.trace.api.ProcessTags import datadog.trace.bootstrap.instrumentation.api.Tags @@ -58,8 +59,11 @@ class PollerRequestFactoryTest extends DDSpecification { void 'remote config provides process tags when enabled = #enabled'() { setup: + // to be changed when activated by default if (enabled) { injectSysConfig(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, "true") + } else if (JavaVirtualMachine.isJavaVersion(21)) { + injectSysConfig(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, "false") } ProcessTags.reset() PollerRequestFactory factory = new PollerRequestFactory(Config.get(), TRACER_VERSION, CONTAINER_ID, ENTITY_ID, INVALID_REMOTE_CONFIG_URL, null)