Skip to content

Commit 768ce77

Browse files
authored
Consult the environment variable when setting the max users frames in code origin probes (#7881)
consult the environment variable when setting the max users frames in code origin probes
1 parent fe6442b commit 768ce77

File tree

9 files changed

+96
-7
lines changed

9 files changed

+96
-7
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public static synchronized void run(
100100
DebuggerContext.initExceptionDebugger(defaultExceptionDebugger);
101101
}
102102
if (config.isDebuggerCodeOriginEnabled()) {
103-
DebuggerContext.initCodeOrigin(new DefaultCodeOriginRecorder(configurationUpdater));
103+
DebuggerContext.initCodeOrigin(new DefaultCodeOriginRecorder(config, configurationUpdater));
104104
}
105105
if (config.isDebuggerInstrumentTheWorld()) {
106106
setupInstrumentTheWorldTransformer(

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.datadog.debugger.exception.Fingerprinter;
77
import com.datadog.debugger.probe.CodeOriginProbe;
88
import com.datadog.debugger.probe.Where;
9+
import datadog.trace.api.Config;
910
import datadog.trace.bootstrap.debugger.CapturedContext;
1011
import datadog.trace.bootstrap.debugger.DebuggerContext;
1112
import datadog.trace.bootstrap.debugger.DebuggerContext.CodeOriginRecorder;
@@ -26,6 +27,8 @@
2627
public class DefaultCodeOriginRecorder implements CodeOriginRecorder {
2728
private static final Logger LOG = LoggerFactory.getLogger(DefaultCodeOriginRecorder.class);
2829

30+
private final Config config;
31+
2932
private final ConfigurationUpdater configurationUpdater;
3033

3134
private final Map<String, CodeOriginProbe> fingerprints = new HashMap<>();
@@ -34,7 +37,8 @@ public class DefaultCodeOriginRecorder implements CodeOriginRecorder {
3437

3538
private final AgentTaskScheduler taskScheduler = AgentTaskScheduler.INSTANCE;
3639

37-
public DefaultCodeOriginRecorder(ConfigurationUpdater configurationUpdater) {
40+
public DefaultCodeOriginRecorder(Config config, ConfigurationUpdater configurationUpdater) {
41+
this.config = config;
3842
this.configurationUpdater = configurationUpdater;
3943
}
4044

@@ -59,7 +63,10 @@ public String captureCodeOrigin(String signature) {
5963

6064
probe =
6165
new CodeOriginProbe(
62-
new ProbeId(UUID.randomUUID().toString(), 0), where.getSignature(), where);
66+
new ProbeId(UUID.randomUUID().toString(), 0),
67+
where.getSignature(),
68+
where,
69+
config.getDebuggerCodeOriginMaxUserFrames());
6370
addFingerprint(fingerprint, probe);
6471

6572
installProbe(probe);

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/CodeOriginProbe.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,17 @@
2626
public class CodeOriginProbe extends LogProbe implements ForceMethodInstrumentation {
2727
private static final Logger LOGGER = LoggerFactory.getLogger(CodeOriginProbe.class);
2828

29+
public final int maxFrames;
30+
2931
private final String signature;
3032

3133
private final boolean entrySpanProbe;
3234

33-
public CodeOriginProbe(ProbeId probeId, String signature, Where where) {
35+
public CodeOriginProbe(ProbeId probeId, String signature, Where where, int maxFrames) {
3436
super(LANGUAGE, probeId, null, where, MethodLocation.EXIT, null, null, true, null, null, null);
3537
this.signature = signature;
3638
this.entrySpanProbe = signature != null;
39+
this.maxFrames = maxFrames;
3740
}
3841

3942
@Override
@@ -133,6 +136,7 @@ private List<StackTraceElement> getUserStackFrames() {
133136
stream ->
134137
stream
135138
.filter(element -> !DebuggerContext.isClassNameExcluded(element.getClassName()))
139+
.limit(maxFrames)
136140
.collect(Collectors.toList()));
137141
}
138142
}

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ protected TestSnapshotListener installProbes(
358358
when(config.getFinalDebuggerSnapshotUrl())
359359
.thenReturn("http://localhost:8126/debugger/v1/input");
360360
when(config.getFinalDebuggerSymDBUrl()).thenReturn("http://localhost:8126/symdb/v1/input");
361+
when(config.getDebuggerCodeOriginMaxUserFrames()).thenReturn(20);
361362
instrumentationListener = new MockInstrumentationListener();
362363
probeStatusSink = mock(ProbeStatusSink.class);
363364

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

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class CodeOriginTest extends CapturingTestBase {
4949
private static final ProbeId CODE_ORIGIN_ID1 = new ProbeId("code origin 1", 0);
5050
private static final ProbeId CODE_ORIGIN_ID2 = new ProbeId("code origin 2", 0);
5151

52+
private static final int MAX_FRAMES = 20;
53+
5254
private DefaultCodeOriginRecorder codeOriginRecorder;
5355

5456
private TestTraceInterceptor traceInterceptor;
@@ -112,6 +114,30 @@ public void withLogProbe() throws IOException, URISyntaxException {
112114
checkResults(testClass, "debug_1", true);
113115
}
114116

117+
@Test
118+
public void stackDepth() throws IOException, URISyntaxException {
119+
final String CLASS_NAME = "com.datadog.debugger.CodeOrigin04";
120+
installProbes(
121+
new CodeOriginProbe(
122+
CODE_ORIGIN_ID1, null, Where.of(CLASS_NAME, "exit", "()", "39"), MAX_FRAMES));
123+
124+
Class<?> testClass = compileAndLoadClass("com.datadog.debugger.CodeOrigin04");
125+
countFrames(testClass, 10);
126+
countFrames(testClass, 100);
127+
}
128+
129+
private void countFrames(Class<?> testClass, int loops) {
130+
int result = Reflect.onClass(testClass).call("main", loops).get();
131+
assertEquals(loops, result);
132+
long count =
133+
traceInterceptor.getTrace().stream()
134+
.filter(s -> s.getOperationName().equals("exit"))
135+
.flatMap(s -> s.getTags().keySet().stream())
136+
.filter(key -> key.contains("frames") && key.endsWith("method"))
137+
.count();
138+
assertTrue(count <= MAX_FRAMES);
139+
}
140+
115141
@Test
116142
public void testCaptureCodeOriginWithSignature() {
117143
installProbes();
@@ -131,9 +157,9 @@ public void testCaptureCodeOriginWithNullSignature() {
131157
@NotNull
132158
private List<LogProbe> codeOriginProbes(String type) {
133159
CodeOriginProbe entry =
134-
new CodeOriginProbe(CODE_ORIGIN_ID1, "()", Where.of(type, "entry", "()", "53"));
160+
new CodeOriginProbe(CODE_ORIGIN_ID1, "()", Where.of(type, "entry", "()", "53"), MAX_FRAMES);
135161
CodeOriginProbe exit =
136-
new CodeOriginProbe(CODE_ORIGIN_ID2, null, Where.of(type, "exit", "()", "60"));
162+
new CodeOriginProbe(CODE_ORIGIN_ID2, null, Where.of(type, "exit", "()", "60"), MAX_FRAMES);
137163
return new ArrayList<>(asList(entry, exit));
138164
}
139165

@@ -164,7 +190,7 @@ protected TestSnapshotListener installProbes(LogProbe... probes) {
164190
TestSnapshotListener listener = super.installProbes(probes);
165191

166192
DebuggerContext.initClassNameFilter(classNameFilter);
167-
codeOriginRecorder = new DefaultCodeOriginRecorder(configurationUpdater);
193+
codeOriginRecorder = new DefaultCodeOriginRecorder(config, configurationUpdater);
168194
DebuggerContext.initCodeOrigin(codeOriginRecorder);
169195

170196
return listener;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.datadog.debugger;
2+
3+
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
4+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
5+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
6+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer.TracerAPI;
7+
import datadog.trace.bootstrap.instrumentation.api.ScopeSource;
8+
9+
public class CodeOrigin04 {
10+
private int intField = 42;
11+
12+
private static TracerAPI tracerAPI = AgentTracer.get();
13+
14+
public static int main(int level) throws ReflectiveOperationException {
15+
doExit(level);
16+
17+
return level;
18+
}
19+
20+
private static void doExit(int level) {
21+
if (level > 0) {
22+
doExit(level - 1);
23+
} else {
24+
AgentSpan span;
25+
AgentScope scope;
26+
span = newSpan("exit");
27+
scope = tracerAPI.activateSpan(span, ScopeSource.MANUAL);
28+
exit();
29+
span.finish();
30+
scope.close();
31+
}
32+
}
33+
34+
private static AgentSpan newSpan(String name) {
35+
return tracerAPI.buildSpan("code origin tests", name).start();
36+
}
37+
38+
private static void exit() {
39+
int x = 47 / 3;
40+
}
41+
42+
}

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
@@ -49,6 +49,7 @@ public final class ConfigDefaults {
4949
static final String DEFAULT_SITE = "datadoghq.com";
5050

5151
static final boolean DEFAULT_CODE_ORIGIN_FOR_SPANS_ENABLED = false;
52+
static final int DEFAULT_CODE_ORIGIN_MAX_USER_FRAMES = 8;
5253
static final boolean DEFAULT_TRACE_SPAN_ORIGIN_ENRICHED = false;
5354
static final boolean DEFAULT_TRACE_ENABLED = true;
5455
public static final boolean DEFAULT_TRACE_OTEL_ENABLED = false;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111
public final class TraceInstrumentationConfig {
1212
public static final String CODE_ORIGIN_FOR_SPANS_ENABLED = "code.origin.for.spans.enabled";
13+
public static final String CODE_ORIGIN_MAX_USER_FRAMES = "code.origin.max.user.frames";
1314
public static final String TRACE_ENABLED = "trace.enabled";
1415
public static final String TRACE_OTEL_ENABLED = "trace.otel.enabled";
1516
public static final String INTEGRATIONS_ENABLED = "integrations.enabled";

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ public static String getHostName() {
403403
private final int debuggerExceptionMaxCapturedFrames;
404404
private final int debuggerExceptionCaptureInterval;
405405
private final boolean debuggerCodeOriginEnabled;
406+
private final int debuggerCodeOriginMaxUserFrames;
406407

407408
private final Set<String> debuggerThirdPartyIncludes;
408409
private final Set<String> debuggerThirdPartyExcludes;
@@ -1533,6 +1534,8 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
15331534
debuggerCodeOriginEnabled =
15341535
configProvider.getBoolean(
15351536
CODE_ORIGIN_FOR_SPANS_ENABLED, DEFAULT_CODE_ORIGIN_FOR_SPANS_ENABLED);
1537+
debuggerCodeOriginMaxUserFrames =
1538+
configProvider.getInteger(CODE_ORIGIN_MAX_USER_FRAMES, DEFAULT_CODE_ORIGIN_MAX_USER_FRAMES);
15361539
debuggerMaxExceptionPerSecond =
15371540
configProvider.getInteger(
15381541
DEBUGGER_MAX_EXCEPTION_PER_SECOND, DEFAULT_DEBUGGER_MAX_EXCEPTION_PER_SECOND);
@@ -2970,6 +2973,10 @@ public boolean isDebuggerCodeOriginEnabled() {
29702973
return debuggerCodeOriginEnabled;
29712974
}
29722975

2976+
public int getDebuggerCodeOriginMaxUserFrames() {
2977+
return debuggerCodeOriginMaxUserFrames;
2978+
}
2979+
29732980
public Set<String> getThirdPartyIncludes() {
29742981
return debuggerThirdPartyIncludes;
29752982
}

0 commit comments

Comments
 (0)