diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/JsonSnapshotSerializer.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/JsonSnapshotSerializer.java index c0d3a104f36..1fbeddfad49 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/JsonSnapshotSerializer.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/JsonSnapshotSerializer.java @@ -6,6 +6,7 @@ import com.squareup.moshi.Json; import com.squareup.moshi.JsonAdapter; import datadog.trace.api.Config; +import datadog.trace.api.ProcessTags; import datadog.trace.bootstrap.debugger.CapturedContext; import datadog.trace.bootstrap.debugger.DebuggerContext; @@ -56,6 +57,9 @@ public static class IntakeRequest { private final String ddtags; + @Json(name = "process_tags") + private final String processTags; + @Json(name = "dd.trace_id") private String traceId; @@ -87,6 +91,8 @@ public IntakeRequest(String service, DebuggerIntakeRequestData debugger) { this.message = debugger.snapshot.getMessage(); this.ddtags = debugger.snapshot.getProbe().getStrTags(); this.timestamp = debugger.snapshot.getTimestamp(); + final CharSequence pt = ProcessTags.getTagsForSerialization(); + this.processTags = pt != null ? pt.toString() : null; } public String getService() { @@ -136,6 +142,10 @@ public long getLoggerThreadId() { public String getLoggerThreadName() { return loggerThreadName; } + + public String getProcessTags() { + return processTags; + } } public static class DebuggerIntakeRequestData { diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/DebuggerSinkTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/DebuggerSinkTest.java index 0486f8d6b0e..9d9cd95ca05 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/DebuggerSinkTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/DebuggerSinkTest.java @@ -1,6 +1,8 @@ package com.datadog.debugger.sink; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -24,6 +26,7 @@ import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Types; import datadog.trace.api.Config; +import datadog.trace.api.ProcessTags; import datadog.trace.bootstrap.debugger.CapturedContext; import datadog.trace.bootstrap.debugger.CapturedContext.CapturedValue; import datadog.trace.bootstrap.debugger.CapturedStackFrame; @@ -44,6 +47,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; @@ -84,8 +89,11 @@ void setUp() { probeStatusSink = new ProbeStatusSink(config, config.getFinalDebuggerSnapshotUrl(), false); } - @Test - public void addSnapshot() throws IOException { + @ParameterizedTest(name = "Process tags enabled ''{0}''") + @ValueSource(booleans = {true, false}) + public void addSnapshot(boolean processTagsEnabled) throws IOException { + when(config.isExperimentalPropagateProcessTagsEnabled()).thenReturn(processTagsEnabled); + ProcessTags.reset(config); DebuggerSink sink = createDefaultDebuggerSink(); DebuggerAgentHelper.injectSerializer(new JsonSnapshotSerializer()); Snapshot snapshot = createSnapshot(); @@ -107,6 +115,13 @@ public void addSnapshot() throws IOException { .getDebugger() .getRuntimeId() .matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")); + if (processTagsEnabled) { + assertNotNull(ProcessTags.getTagsForSerialization()); + assertEquals( + ProcessTags.getTagsForSerialization().toString(), intakeRequest.getProcessTags()); + } else { + assertNull(intakeRequest.getProcessTags()); + } } @Test diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/SnapshotSinkTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/SnapshotSinkTest.java index 1d03482fbf9..f919f316129 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/SnapshotSinkTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/sink/SnapshotSinkTest.java @@ -1,6 +1,8 @@ package com.datadog.debugger.sink; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.Mockito.verify; @@ -14,6 +16,7 @@ import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Types; import datadog.trace.api.Config; +import datadog.trace.api.ProcessTags; import datadog.trace.bootstrap.debugger.DebuggerContext; import datadog.trace.bootstrap.debugger.Limits; import datadog.trace.bootstrap.debugger.ProbeId; @@ -26,6 +29,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; @@ -63,8 +68,11 @@ void setUp() { probeStatusSink = new ProbeStatusSink(config, config.getFinalDebuggerSnapshotUrl(), false); } - @Test - public void addHighRateSnapshot() throws IOException { + @ParameterizedTest(name = "Process tags enabled ''{0}''") + @ValueSource(booleans = {true, false}) + public void addHighRateSnapshot(boolean processTagsEnabled) throws IOException { + when(config.isExperimentalPropagateProcessTagsEnabled()).thenReturn(processTagsEnabled); + ProcessTags.reset(config); SnapshotSink snapshotSink = createSnapshotSink(); snapshotSink.start(); Snapshot snapshot = createSnapshot(); @@ -86,6 +94,13 @@ public void addHighRateSnapshot() throws IOException { .getDebugger() .getRuntimeId() .matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")); + if (processTagsEnabled) { + assertNotNull(ProcessTags.getTagsForSerialization()); + assertEquals( + ProcessTags.getTagsForSerialization().toString(), intakeRequest.getProcessTags()); + } else { + assertNull(intakeRequest.getProcessTags()); + } } @Test 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 4361a8e5573..ec9ddc9203b 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 @@ -27,6 +27,8 @@ import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; public class TracerDebuggerIntegrationTest extends BaseIntegrationTest { @@ -44,9 +46,10 @@ protected String getAppId() { return TagsHelper.sanitize("SpringBootTestApplication"); } - @Test + @ParameterizedTest(name = "Process tags enabled ''{0}''") + @ValueSource(booleans = {true, false}) @DisplayName("testTracer") - void testTracer() throws Exception { + void testTracer(boolean processTagsEnabled) throws Exception { LogProbe logProbe = LogProbe.builder() .probeId(PROBE_ID) @@ -56,13 +59,22 @@ void testTracer() throws Exception { "(HttpServletRequest, HttpServletResponse)") .captureSnapshot(true) .build(); - JsonSnapshotSerializer.IntakeRequest request = doTestTracer(logProbe); + JsonSnapshotSerializer.IntakeRequest request = doTestTracer(logProbe, processTagsEnabled); Snapshot snapshot = request.getDebugger().getSnapshot(); assertEquals(PROBE_ID.getId(), snapshot.getProbe().getId()); assertTrue(Pattern.matches("[0-9a-f]+", request.getTraceId())); assertTrue(Pattern.matches("\\d+", request.getSpanId())); assertFalse( logHasErrors(logFilePath, it -> it.contains("TypePool$Resolution$NoSuchTypeException"))); + if (processTagsEnabled) { + assertNotNull(request.getProcessTags()); + assertTrue( + request + .getProcessTags() + .contains("entrypoint.name:" + TagsHelper.sanitize(DEBUGGER_TEST_APP_CLASS))); + } else { + assertNull(request.getProcessTags()); + } } @Test @@ -146,9 +158,18 @@ void testTracerLineDynamicLogProbe() throws Exception { } private JsonSnapshotSerializer.IntakeRequest doTestTracer(LogProbe logProbe) throws Exception { + return doTestTracer(logProbe, false); + } + + private JsonSnapshotSerializer.IntakeRequest doTestTracer( + LogProbe logProbe, boolean enableProcessTags) throws Exception { setCurrentConfiguration(createConfig(logProbe)); String httpPort = String.valueOf(PortUtils.randomOpenPort()); - targetProcess = createProcessBuilder(logFilePath, "--server.port=" + httpPort).start(); + ProcessBuilder processBuilder = createProcessBuilder(logFilePath, "--server.port=" + httpPort); + if (enableProcessTags) { + processBuilder.environment().put("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED", "true"); + } + targetProcess = processBuilder.start(); // assert in logs app started waitForSpecificLogLine( logFilePath,