diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java index 9695e511520..0d4ac850c14 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java @@ -725,7 +725,7 @@ private void addFilteredCaptureExpressions( } private void processCaptureExpressions(CapturedContext context, LogStatus logStatus) { - if (captureExpressions == null) { + if (captureExpressions == null || !logStatus.shouldSend()) { return; } for (CaptureExpression captureExpression : captureExpressions) { diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java index 9d70e07c3e7..e48b7514685 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java @@ -3020,6 +3020,31 @@ public void captureExpressionsWithNullCondition() throws IOException, URISyntaxE assertEquals("Cannot dereference field: fld", evaluationErrors.get(0).getMessage()); } + @Test + public void captureExpressionsWithRejectingCondition() throws IOException, URISyntaxException { + final String CLASS_NAME = "CapturedSnapshot08"; + LogProbe probe = + createProbeBuilder(PROBE_ID, CLASS_NAME, "doit", null) + .evaluateAt(MethodLocation.EXIT) + .captureSnapshot(false) + .when(new ProbeCondition(DSL.when(DSL.eq(DSL.value(1), DSL.value(2))), "1 == 2")) + .template("plain log", Collections.emptyList()) + .captureExpressions( + Collections.singletonList( + new LogProbe.CaptureExpression( + "unknown_symbol", + new ValueScript(ref("doesNotExist"), "doesNotExist"), + null))) + .build(); + TestSnapshotListener listener = installProbes(probe); + Class testClass = compileAndLoadClass(CLASS_NAME); + for (int i = 0; i < 5; i++) { + int result = Reflect.onClass(testClass).call("main", "1").get(); + assertEquals(3, result); + } + assertEquals(0, listener.snapshots.size()); + } + @Test public void captureExpressionsPrimitives() throws IOException, URISyntaxException { final String CLASS_NAME = "CapturedSnapshot08"; diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java index a3c25c48021..c74396b10e5 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java @@ -5,12 +5,16 @@ import static java.lang.String.format; import static java.lang.Thread.currentThread; import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import com.datadog.debugger.agent.DebuggerAgentHelper; +import com.datadog.debugger.el.DSL; +import com.datadog.debugger.el.ProbeCondition; +import com.datadog.debugger.el.ValueScript; import com.datadog.debugger.probe.LogProbe.Builder; import com.datadog.debugger.probe.LogProbe.LogStatus; import com.datadog.debugger.sink.DebuggerSink; @@ -19,6 +23,7 @@ import datadog.context.ContextScope; import datadog.trace.api.Config; import datadog.trace.api.IdGenerationStrategy; +import datadog.trace.api.sampling.ConstantSampler; import datadog.trace.bootstrap.debugger.CapturedContext; import datadog.trace.bootstrap.debugger.EvaluationError; import datadog.trace.bootstrap.debugger.MethodLocation; @@ -342,6 +347,49 @@ public void fillSnapshot_shouldSend_evalErrors() { "errorExit", snapshot.getCaptures().getReturn().getCapturedThrowable().getMessage()); } + @Test + public void captureExpressionsInActiveDebugSession() { + DebuggerAgentHelper.injectSink(new DebuggerSink(getConfig(), mock(ProbeStatusSink.class))); + TracerAPI tracer = + CoreTracer.builder().idGenerationStrategy(IdGenerationStrategy.fromName("random")).build(); + AgentTracer.registerIfAbsent(tracer); + AgentSpan span = tracer.startSpan("log probe capture expression testing", "test span"); + try (ContextScope scope = tracer.activateManualSpan(span)) { + span.setTag(Tags.PROPAGATED_DEBUG, DEBUG_SESSION_ID + ":1"); + // the probe sampler always rejects: the active session decision must still win + ProbeRateLimiter.setSamplerSupplier(rate -> new ConstantSampler(false)); + LogProbe logProbe = + createLog("log line") + .probeId(ProbeId.newId()) + .evaluateAt(MethodLocation.EXIT) + .tags(format("session_id:%s", DEBUG_SESSION_ID)) + .when(new ProbeCondition(DSL.when(DSL.eq(DSL.value(1), DSL.value(1))), "1 == 1")) + .captureExpressions( + singletonList( + new LogProbe.CaptureExpression( + "greeting", new ValueScript(DSL.value("hello"), "'hello'"), null))) + .build(); + logProbe.initSamplers(); + CapturedContext entryContext = capturedContext(span, logProbe); + CapturedContext exitContext = capturedContext(span, logProbe); + logProbe.evaluate(entryContext, new LogStatus(logProbe), MethodLocation.ENTRY, false); + logProbe.evaluate(exitContext, new LogStatus(logProbe), MethodLocation.EXIT, false); + Snapshot snapshot = new Snapshot(currentThread(), logProbe, 3); + assertTrue(logProbe.fillSnapshot(entryContext, exitContext, emptyList(), snapshot)); + assertEquals( + "hello", + snapshot + .getCaptures() + .getReturn() + .getCaptureExpressions() + .get("greeting") + .getValue() + .toString()); + } finally { + ProbeRateLimiter.setSamplerSupplier(null); + } + } + private Builder createLog(String template) { return LogProbe.builder() .language(LANGUAGE)