Skip to content

Commit 19ce7f1

Browse files
authored
Introduce new flag to enable the live debugger specifically (#8418)
1 parent bde8272 commit 19ce7f1

7 files changed

Lines changed: 70 additions & 46 deletions

File tree

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/codeorigin/DefaultCodeOriginRecorder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private CodeOriginProbe createProbe(
121121

122122
// i think this check is unnecessary at this point time but leaving for now to be safe
123123
if (installed == null) {
124-
if (Config.get().isDynamicInstrumentationEnabled()) {
124+
if (Config.get().isDistributedDebuggerEnabled()) {
125125
registerLogProbe(probe);
126126
}
127127
installProbes();

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/origin/CodeOriginTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public void before() {
8888
tracer.addTraceInterceptor(traceInterceptor);
8989

9090
setFieldInConfig(Config.get(), "debuggerCodeOriginEnabled", true);
91+
setFieldInConfig(Config.get(), "distributedDebuggerEnabled", true);
9192
setFieldInConfig(InstrumenterConfig.get(), "codeOriginEnabled", true);
9293
}
9394

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import datadog.trace.bootstrap.debugger.EvaluationError;
2323
import datadog.trace.bootstrap.debugger.MethodLocation;
2424
import datadog.trace.bootstrap.debugger.ProbeId;
25+
import datadog.trace.bootstrap.debugger.ProbeRateLimiter;
2526
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
2627
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
2728
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -30,6 +31,7 @@
3031
import datadog.trace.bootstrap.instrumentation.api.Tags;
3132
import datadog.trace.core.CoreTracer;
3233
import java.util.stream.Stream;
34+
import org.jetbrains.annotations.NotNull;
3335
import org.junit.jupiter.api.Assertions;
3436
import org.junit.jupiter.api.Test;
3537
import org.junit.jupiter.params.ParameterizedTest;
@@ -41,6 +43,7 @@ public class LogProbeTest {
4143
private static final String LANGUAGE = "java";
4244
private static final ProbeId PROBE_ID = new ProbeId("beae1807-f3b0-4ea8-a74f-826790c5e6f8", 0);
4345
private static final String DEBUG_SESSION_ID = "TestSession";
46+
private static final int BUDGET_RUNS = 1100;
4447

4548
@Test
4649
public void testCapture() {
@@ -81,65 +84,68 @@ public void noDebugSession() {
8184

8285
@Test
8386
public void budgets() {
84-
BudgetSink sink = new BudgetSink(getConfig(), mock(ProbeStatusSink.class));
85-
DebuggerAgentHelper.injectSink(sink);
87+
try {
88+
ProbeRateLimiter.setGlobalSnapshotRate(-1);
89+
TracerAPI tracer =
90+
CoreTracer.builder()
91+
.idGenerationStrategy(IdGenerationStrategy.fromName("random"))
92+
.build();
93+
AgentTracer.registerIfAbsent(tracer);
94+
String sessionId = "12345";
8695

87-
TracerAPI tracer =
88-
CoreTracer.builder().idGenerationStrategy(IdGenerationStrategy.fromName("random")).build();
89-
AgentTracer.registerIfAbsent(tracer);
90-
int runs = 100;
91-
for (int i = 0; i < runs; i++) {
92-
runTrace(tracer, true);
93-
}
94-
assertEquals(runs * LogProbe.CAPTURING_PROBE_BUDGET, sink.captures);
96+
Result result = getResult(tracer, sessionId, true, null);
97+
assertEquals(BUDGET_RUNS * LogProbe.CAPTURING_PROBE_BUDGET, result.sink.captures);
9598

96-
sink = new BudgetSink(getConfig(), mock(ProbeStatusSink.class));
97-
DebuggerAgentHelper.injectSink(sink);
98-
runs = 1010;
99-
for (int i = 0; i < runs; i++) {
100-
runTrace(tracer, false);
101-
}
102-
assertEquals(runs * LogProbe.NON_CAPTURING_PROBE_BUDGET, sink.highRate);
103-
}
99+
result = getResult(tracer, sessionId, false, null);
100+
assertEquals(BUDGET_RUNS * LogProbe.NON_CAPTURING_PROBE_BUDGET, result.sink.highRate);
104101

105-
@Test
106-
public void budgetsOnLineProbes() {
107-
BudgetSink sink = new BudgetSink(getConfig(), mock(ProbeStatusSink.class));
108-
DebuggerAgentHelper.injectSink(sink);
102+
// run without a session
103+
result = getResult(tracer, null, true, 100);
104+
assertEquals(result.count, result.sink.captures);
109105

110-
TracerAPI tracer =
111-
CoreTracer.builder().idGenerationStrategy(IdGenerationStrategy.fromName("random")).build();
112-
AgentTracer.registerIfAbsent(tracer);
113-
int runs = 100;
114-
for (int i = 0; i < runs; i++) {
115-
runTrace(tracer, true, 100);
106+
result = getResult(tracer, null, false, 100);
107+
assertEquals(result.count, result.sink.highRate);
108+
} finally {
109+
ProbeRateLimiter.resetGlobalRate();
116110
}
117-
assertEquals(runs * LogProbe.CAPTURING_PROBE_BUDGET, sink.captures);
111+
}
118112

119-
sink = new BudgetSink(getConfig(), mock(ProbeStatusSink.class));
113+
@NotNull
114+
private Result getResult(
115+
TracerAPI tracer, String sessionId, boolean captureSnapshot, Integer line) {
116+
BudgetSink sink = new BudgetSink(getConfig(), mock(ProbeStatusSink.class));
120117
DebuggerAgentHelper.injectSink(sink);
121-
runs = 1010;
122-
for (int i = 0; i < runs; i++) {
123-
runTrace(tracer, false, 100);
118+
int count = 0;
119+
for (int i = 0; i < BUDGET_RUNS; i++) {
120+
count += runTrace(tracer, captureSnapshot, line, sessionId);
124121
}
125-
assertEquals(runs * LogProbe.NON_CAPTURING_PROBE_BUDGET, sink.highRate);
122+
return new Result(sink, count);
126123
}
127124

128-
private void runTrace(TracerAPI tracer, boolean captureSnapshot) {
129-
runTrace(tracer, captureSnapshot, null);
125+
private static class Result {
126+
final int count;
127+
final BudgetSink sink;
128+
129+
private Result(BudgetSink sink, int count) {
130+
this.sink = sink;
131+
this.count = count;
132+
}
130133
}
131134

132-
private void runTrace(TracerAPI tracer, boolean captureSnapshot, Integer line) {
135+
private int runTrace(TracerAPI tracer, boolean captureSnapshot, Integer line, String sessionId) {
133136
AgentSpan span = tracer.startSpan("budget testing", "test span");
134-
span.setTag(Tags.PROPAGATED_DEBUG, "12345:1");
137+
if (sessionId != null) {
138+
span.setTag(Tags.PROPAGATED_DEBUG, sessionId + ":1");
139+
}
135140
try (AgentScope scope = tracer.activateSpan(span, ScopeSource.MANUAL)) {
141+
Builder builder =
142+
createLog("Budget testing").probeId(ProbeId.newId()).captureSnapshot(captureSnapshot);
143+
if (sessionId != null) {
144+
builder.tags("session_id:" + sessionId);
145+
}
146+
LogProbe logProbe = builder.build();
147+
ProbeRateLimiter.setRate(logProbe.id, -1, captureSnapshot);
136148

137-
LogProbe logProbe =
138-
createLog("I'm in a debug session")
139-
.probeId(ProbeId.newId())
140-
.tags("session_id:12345")
141-
.captureSnapshot(captureSnapshot)
142-
.build();
143149
CapturedContext entryContext = capturedContext(span, logProbe);
144150
CapturedContext exitContext = capturedContext(span, logProbe);
145151
logProbe.evaluate(entryContext, new LogStatus(logProbe), MethodLocation.ENTRY);
@@ -158,7 +164,11 @@ private void runTrace(TracerAPI tracer, boolean captureSnapshot, Integer line) {
158164
logProbe.commit(entryContext, line);
159165
}
160166
}
161-
assertEquals(runs, span.getLocalRootSpan().getTag(format("_dd.ld.probe_id.%s", logProbe.id)));
167+
if (sessionId != null) {
168+
assertEquals(
169+
runs, span.getLocalRootSpan().getTag(format("_dd.ld.probe_id.%s", logProbe.id)));
170+
}
171+
return runs;
162172
}
163173
}
164174

@@ -343,6 +353,7 @@ private Builder createLog(String template) {
343353
private static class BudgetSink extends DebuggerSink {
344354

345355
public int captures;
356+
346357
public int highRate;
347358

348359
public BudgetSink(Config config, ProbeStatusSink probeStatusSink) {

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public final class ConfigDefaults {
196196
static final boolean DEFAULT_DEBUGGER_EXCEPTION_CAPTURE_INTERMEDIATE_SPANS_ENABLED = true;
197197
static final int DEFAULT_DEBUGGER_EXCEPTION_MAX_CAPTURED_FRAMES = 3;
198198
static final int DEFAULT_DEBUGGER_EXCEPTION_CAPTURE_INTERVAL_SECONDS = 60 * 60;
199+
static final boolean DEFAULT_DISTRIBUTED_DEBUGGER_ENABLED = false;
199200

200201
static final boolean DEFAULT_TRACE_REPORT_HOSTNAME = false;
201202
static final String DEFAULT_TRACE_ANNOTATIONS = null;

dd-trace-api/src/main/java/datadog/trace/api/config/DebuggerConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public final class DebuggerConfig {
5858
"exception.replay.capture.interval.seconds";
5959
public static final String DEBUGGER_EXCEPTION_CAPTURE_INTERMEDIATE_SPANS_ENABLED =
6060
"exception.replay.capture.intermediate.spans.enabled";
61+
public static final String DISTRIBUTED_DEBUGGER_ENABLED = "distributed.debugger.enabled";
6162
public static final String THIRD_PARTY_INCLUDES = "third.party.includes";
6263
public static final String THIRD_PARTY_EXCLUDES = "third.party.excludes";
6364

dd-trace-core/src/main/java/datadog/trace/core/StatusLogger.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public void toJson(JsonWriter writer, Config config) throws IOException {
116116
writer.value(config.isDebuggerExceptionEnabled());
117117
writer.name("debugger_span_origin_enabled");
118118
writer.value(config.isDebuggerCodeOriginEnabled());
119+
writer.name("debugger_distributed_debugger_enabled");
120+
writer.value(config.isDistributedDebuggerEnabled());
119121
writer.name("appsec_enabled");
120122
writer.value(config.getAppSecActivation().toString());
121123
writer.name("appsec_rules_file_path");

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ public static String getHostName() {
422422
private final int debuggerExceptionCaptureInterval;
423423
private final boolean debuggerCodeOriginEnabled;
424424
private final int debuggerCodeOriginMaxUserFrames;
425+
private final boolean distributedDebuggerEnabled;
425426

426427
private final Set<String> debuggerThirdPartyIncludes;
427428
private final Set<String> debuggerThirdPartyExcludes;
@@ -1559,6 +1560,9 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
15591560
dynamicInstrumentationEnabled =
15601561
configProvider.getBoolean(
15611562
DYNAMIC_INSTRUMENTATION_ENABLED, DEFAULT_DYNAMIC_INSTRUMENTATION_ENABLED);
1563+
distributedDebuggerEnabled =
1564+
configProvider.getBoolean(
1565+
DISTRIBUTED_DEBUGGER_ENABLED, DEFAULT_DISTRIBUTED_DEBUGGER_ENABLED);
15621566
dynamicInstrumentationUploadTimeout =
15631567
configProvider.getInteger(
15641568
DYNAMIC_INSTRUMENTATION_UPLOAD_TIMEOUT, DEFAULT_DYNAMIC_INSTRUMENTATION_UPLOAD_TIMEOUT);
@@ -3171,6 +3175,10 @@ public int getDebuggerCodeOriginMaxUserFrames() {
31713175
return debuggerCodeOriginMaxUserFrames;
31723176
}
31733177

3178+
public boolean isDistributedDebuggerEnabled() {
3179+
return distributedDebuggerEnabled;
3180+
}
3181+
31743182
public Set<String> getThirdPartyIncludes() {
31753183
return debuggerThirdPartyIncludes;
31763184
}

0 commit comments

Comments
 (0)