Skip to content

Commit 4abf841

Browse files
authored
Implement the DebuggerProbe (#7588)
Implement the DebuggerProbe. [DEBUG-2719] Update code origin tags [DEBUG-2722]
1 parent efc6f52 commit 4abf841

File tree

45 files changed

+1287
-758
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1287
-758
lines changed

dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/DebuggerContext.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ public interface ExceptionDebugger {
6767
void handleException(Throwable t, AgentSpan span);
6868
}
6969

70-
public interface SpanDebugger {
71-
String captureSnapshot(String signature);
70+
public interface CodeOriginRecorder {
71+
String captureCodeOrigin(String signature);
7272
}
7373

7474
private static volatile ProbeResolver probeResolver;
@@ -77,7 +77,7 @@ public interface SpanDebugger {
7777
private static volatile Tracer tracer;
7878
private static volatile ValueSerializer valueSerializer;
7979
private static volatile ExceptionDebugger exceptionDebugger;
80-
private static volatile SpanDebugger spanDebugger;
80+
private static volatile CodeOriginRecorder codeOriginRecorder;
8181

8282
public static void initProbeResolver(ProbeResolver probeResolver) {
8383
DebuggerContext.probeResolver = probeResolver;
@@ -103,8 +103,8 @@ public static void initExceptionDebugger(ExceptionDebugger exceptionDebugger) {
103103
DebuggerContext.exceptionDebugger = exceptionDebugger;
104104
}
105105

106-
public static void initSpanDebugger(SpanDebugger spanDebugger) {
107-
DebuggerContext.spanDebugger = spanDebugger;
106+
public static void initCodeOrigin(CodeOriginRecorder codeOriginRecorder) {
107+
DebuggerContext.codeOriginRecorder = codeOriginRecorder;
108108
}
109109

110110
/**
@@ -342,14 +342,14 @@ public static void commit(
342342
}
343343
}
344344

345-
public static String captureSnapshot(String signature) {
345+
public static String captureCodeOrigin(String signature) {
346346
try {
347-
SpanDebugger debugger = spanDebugger;
348-
if (debugger != null) {
349-
return debugger.captureSnapshot(signature);
347+
CodeOriginRecorder recorder = codeOriginRecorder;
348+
if (recorder != null) {
349+
return recorder.captureCodeOrigin(signature);
350350
}
351351
} catch (Exception ex) {
352-
LOGGER.debug("Error in addSnapshot: ", ex);
352+
LOGGER.debug("Error in captureCodeOrigin: ", ex);
353353
}
354354
return null;
355355
}
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
package datadog.trace.bootstrap.debugger.spanorigin;
22

3-
import static datadog.trace.bootstrap.debugger.DebuggerContext.captureSnapshot;
3+
import static datadog.trace.bootstrap.debugger.DebuggerContext.captureCodeOrigin;
44
import static java.util.Arrays.stream;
55

66
import datadog.trace.api.InstrumenterConfig;
77
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
88
import java.lang.reflect.Method;
99
import java.util.stream.Collectors;
1010

11-
public class SpanOriginInfo {
12-
public static void entry(AgentSpan span, Method method) {
13-
if (InstrumenterConfig.get().isSpanOriginEnabled()) {
11+
public class CodeOriginInfo {
12+
public static void entry(Method method) {
13+
if (InstrumenterConfig.get().isCodeOriginEnabled()) {
1414
String signature =
1515
stream(method.getParameterTypes())
1616
.map(Class::getName)
1717
.collect(Collectors.joining(",", "(", ")"));
18-
captureSnapshot(signature);
18+
captureCodeOrigin(signature);
1919
}
2020
}
2121

2222
public static void exit(AgentSpan span) {
23-
if (InstrumenterConfig.get().isSpanOriginEnabled()) {
24-
span.getLocalRootSpan().setMetaStruct(captureSnapshot(null), span);
23+
if (InstrumenterConfig.get().isCodeOriginEnabled()) {
24+
String probeId = captureCodeOrigin(null);
25+
if (span != null) {
26+
span.getLocalRootSpan().setTag(probeId, span);
27+
}
2528
}
2629
}
2730
}

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

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.datadog.debugger.agent;
22

3+
import com.datadog.debugger.probe.DebuggerProbe;
34
import com.datadog.debugger.probe.ExceptionProbe;
45
import com.datadog.debugger.probe.LogProbe;
56
import com.datadog.debugger.probe.MetricProbe;
@@ -65,6 +66,7 @@ public int hashCode() {
6566
private final Collection<MetricProbe> metricProbes;
6667
private final Collection<LogProbe> logProbes;
6768
private final Collection<SpanProbe> spanProbes;
69+
private final Collection<DebuggerProbe> debuggerProbes;
6870
private final Collection<SpanDecorationProbe> spanDecorationProbes;
6971
private final FilterList allowList;
7072
private final FilterList denyList;
@@ -79,14 +81,15 @@ public Configuration(
7981
Collection<MetricProbe> metricProbes,
8082
Collection<LogProbe> logProbes,
8183
Collection<SpanProbe> spanProbes) {
82-
this(serviceName, metricProbes, logProbes, spanProbes, null, null, null, null);
84+
this(serviceName, metricProbes, logProbes, spanProbes, null, null, null, null, null);
8385
}
8486

8587
public Configuration(
8688
String serviceName,
8789
Collection<MetricProbe> metricProbes,
8890
Collection<LogProbe> logProbes,
8991
Collection<SpanProbe> spanProbes,
92+
Collection<DebuggerProbe> debuggerProbes,
9093
Collection<SpanDecorationProbe> spanDecorationProbes,
9194
FilterList allowList,
9295
FilterList denyList,
@@ -95,6 +98,7 @@ public Configuration(
9598
this.metricProbes = metricProbes;
9699
this.logProbes = logProbes;
97100
this.spanProbes = spanProbes;
101+
this.debuggerProbes = debuggerProbes;
98102
this.spanDecorationProbes = spanDecorationProbes;
99103
this.allowList = allowList;
100104
this.denyList = denyList;
@@ -117,6 +121,10 @@ public Collection<SpanProbe> getSpanProbes() {
117121
return spanProbes;
118122
}
119123

124+
public Collection<DebuggerProbe> getDebuggerProbes() {
125+
return debuggerProbes;
126+
}
127+
120128
public Collection<SpanDecorationProbe> getSpanDecorationProbes() {
121129
return spanDecorationProbes;
122130
}
@@ -135,6 +143,9 @@ public LogProbe.Sampling getSampling() {
135143

136144
public Collection<ProbeDefinition> getDefinitions() {
137145
Collection<ProbeDefinition> result = new ArrayList<>();
146+
if (debuggerProbes != null) {
147+
result.addAll(debuggerProbes);
148+
}
138149
if (metricProbes != null) {
139150
result.addAll(metricProbes);
140151
}
@@ -198,6 +209,7 @@ public static class Builder {
198209
private List<MetricProbe> metricProbes = null;
199210
private List<LogProbe> logProbes = null;
200211
private List<SpanProbe> spanProbes = null;
212+
private List<DebuggerProbe> debuggerProbes = null;
201213
private List<SpanDecorationProbe> spanDecorationProbes = null;
202214
private FilterList allowList = null;
203215
private FilterList denyList = null;
@@ -214,6 +226,7 @@ public Configuration.Builder add(Collection<? extends ProbeDefinition> definitio
214226
}
215227
for (ProbeDefinition definition : definitions) {
216228
if (definition instanceof MetricProbe) add((MetricProbe) definition);
229+
if (definition instanceof DebuggerProbe) add((DebuggerProbe) definition);
217230
if (definition instanceof LogProbe) add((LogProbe) definition);
218231
if (definition instanceof SpanProbe) add((SpanProbe) definition);
219232
if (definition instanceof SpanDecorationProbe) add((SpanDecorationProbe) definition);
@@ -245,6 +258,14 @@ public Configuration.Builder add(SpanProbe probe) {
245258
return this;
246259
}
247260

261+
public Configuration.Builder add(DebuggerProbe probe) {
262+
if (debuggerProbes == null) {
263+
debuggerProbes = new ArrayList<>();
264+
}
265+
debuggerProbes.add(probe);
266+
return this;
267+
}
268+
248269
public Configuration.Builder add(SpanDecorationProbe probe) {
249270
if (spanDecorationProbes == null) {
250271
spanDecorationProbes = new ArrayList<>();
@@ -300,6 +321,16 @@ public Configuration.Builder addSpanProbes(Collection<SpanProbe> probes) {
300321
return this;
301322
}
302323

324+
public Configuration.Builder addDebuggerProbes(Collection<DebuggerProbe> probes) {
325+
if (probes == null) {
326+
return this;
327+
}
328+
for (DebuggerProbe probe : probes) {
329+
add(probe);
330+
}
331+
return this;
332+
}
333+
303334
public Configuration.Builder addSpanDecorationProbes(Collection<SpanDecorationProbe> probes) {
304335
if (probes == null) {
305336
return this;
@@ -346,6 +377,7 @@ public Configuration.Builder add(Configuration other) {
346377
addMetricProbes(other.getMetricProbes());
347378
addLogProbes(other.getLogProbes());
348379
addSpanProbes(other.getSpanProbes());
380+
addDebuggerProbes(other.getDebuggerProbes());
349381
addSpanDecorationProbes(other.getSpanDecorationProbes());
350382
addAllowList(other.getAllowList());
351383
addDenyList(other.getDenyList());
@@ -359,6 +391,7 @@ public Configuration build() {
359391
metricProbes,
360392
logProbes,
361393
spanProbes,
394+
debuggerProbes,
362395
spanDecorationProbes,
363396
allowList,
364397
denyList,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public interface ConfigurationAcceptor {
77
enum Source {
88
REMOTE_CONFIG,
9-
SPAN_DEBUG,
9+
CODE_ORIGIN,
1010
EXCEPTION
1111
}
1212

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import static com.datadog.debugger.agent.ConfigurationAcceptor.Source.REMOTE_CONFIG;
44
import static datadog.trace.util.AgentThreadFactory.AGENT_THREAD_GROUP;
55

6+
import com.datadog.debugger.codeorigin.CodeOriginProbeManager;
7+
import com.datadog.debugger.codeorigin.DefaultCodeOriginRecorder;
68
import com.datadog.debugger.exception.DefaultExceptionDebugger;
79
import com.datadog.debugger.exception.ExceptionProbeManager;
810
import com.datadog.debugger.sink.DebuggerSink;
911
import com.datadog.debugger.sink.ProbeStatusSink;
1012
import com.datadog.debugger.sink.SnapshotSink;
1113
import com.datadog.debugger.sink.SymbolSink;
12-
import com.datadog.debugger.snapshot.DefaultSpanDebugger;
1314
import com.datadog.debugger.symbol.SymDBEnablement;
1415
import com.datadog.debugger.symbol.SymbolAggregator;
1516
import com.datadog.debugger.uploader.BatchUploader;
@@ -102,9 +103,10 @@ public static synchronized void run(
102103
config.getDebuggerMaxExceptionPerSecond());
103104
DebuggerContext.initExceptionDebugger(defaultExceptionDebugger);
104105
}
105-
if (config.isDebuggerSpanDebugEnabled()) {
106-
DebuggerContext.initSpanDebugger(
107-
new DefaultSpanDebugger(configurationUpdater, classNameFiltering));
106+
if (config.isDebuggerCodeOriginEnabled()) {
107+
DebuggerContext.initCodeOrigin(
108+
new DefaultCodeOriginRecorder(
109+
new CodeOriginProbeManager(configurationUpdater, classNameFiltering)));
108110
}
109111
if (config.isDebuggerInstrumentTheWorld()) {
110112
setupInstrumentTheWorldTransformer(

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

+25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static com.datadog.debugger.agent.ConfigurationAcceptor.Source.REMOTE_CONFIG;
44

5+
import com.datadog.debugger.probe.DebuggerProbe;
56
import com.datadog.debugger.probe.LogProbe;
67
import com.datadog.debugger.probe.MetricProbe;
78
import com.datadog.debugger.probe.ProbeDefinition;
@@ -28,13 +29,15 @@
2829
import org.slf4j.LoggerFactory;
2930

3031
public class DebuggerProductChangesListener implements ProductListener {
32+
public static final int MAX_ALLOWED_DEBUGGER_PROBES = 100;
3133
public static final int MAX_ALLOWED_METRIC_PROBES = 100;
3234
public static final int MAX_ALLOWED_LOG_PROBES = 100;
3335
public static final int MAX_ALLOWED_SPAN_PROBES = 100;
3436
public static final int MAX_ALLOWED_SPAN_DECORATION_PROBES = 100;
3537
public static final String LOG_PROBE_PREFIX = "logProbe_";
3638
public static final String METRIC_PROBE_PREFIX = "metricProbe_";
3739
public static final String SPAN_PROBE_PREFIX = "spanProbe_";
40+
public static final String DEBUGGER_PROBE_PREFIX = "debuggerProbe_";
3841
public static final String SPAN_DECORATION_PROBE_PREFIX = "spanDecorationProbe_";
3942
private static final Logger LOGGER =
4043
LoggerFactory.getLogger(DebuggerProductChangesListener.class);
@@ -52,6 +55,9 @@ static class Adapter {
5255
static final JsonAdapter<SpanProbe> SPAN_PROBE_JSON_ADAPTER =
5356
MoshiHelper.createMoshiConfig().adapter(SpanProbe.class);
5457

58+
static final JsonAdapter<DebuggerProbe> DEBUGGER_PROBE_JSON_ADAPTER =
59+
MoshiHelper.createMoshiConfig().adapter(DebuggerProbe.class);
60+
5561
static final JsonAdapter<SpanDecorationProbe> SPAN_DECORATION_PROBE_JSON_ADAPTER =
5662
MoshiHelper.createMoshiConfig().adapter(SpanDecorationProbe.class);
5763

@@ -71,6 +77,10 @@ static SpanProbe deserializeSpanProbe(byte[] content) throws IOException {
7177
return deserialize(SPAN_PROBE_JSON_ADAPTER, content);
7278
}
7379

80+
static DebuggerProbe deserializeDebuggerProbe(byte[] content) throws IOException {
81+
return deserialize(DEBUGGER_PROBE_JSON_ADAPTER, content);
82+
}
83+
7484
static SpanDecorationProbe deserializeSpanDecorationProbe(byte[] content) throws IOException {
7585
return deserialize(SPAN_DECORATION_PROBE_JSON_ADAPTER, content);
7686
}
@@ -108,6 +118,9 @@ public void accept(ConfigKey configKey, byte[] content, PollingRateHinter pollin
108118
} else if (configId.startsWith(SPAN_PROBE_PREFIX)) {
109119
SpanProbe spanProbe = Adapter.deserializeSpanProbe(content);
110120
configChunks.put(configId, definitions -> definitions.add(spanProbe));
121+
} else if (configId.startsWith(DEBUGGER_PROBE_PREFIX)) {
122+
DebuggerProbe debuggerProbe = Adapter.deserializeDebuggerProbe(content);
123+
configChunks.put(configId, definitions -> definitions.add(debuggerProbe));
111124
} else if (configId.startsWith(SPAN_DECORATION_PROBE_PREFIX)) {
112125
SpanDecorationProbe spanDecorationProbe = Adapter.deserializeSpanDecorationProbe(content);
113126
configChunks.put(configId, definitions -> definitions.add(spanDecorationProbe));
@@ -148,6 +161,7 @@ public void commit(PollingRateHinter pollingRateHinter) {
148161

149162
static class DefinitionBuilder {
150163
private final Collection<ProbeDefinition> definitions = new ArrayList<>();
164+
private int debuggerProbeCount = 0;
151165
private int metricProbeCount = 0;
152166
private int logProbeCount = 0;
153167
private int spanProbeCount = 0;
@@ -180,6 +194,15 @@ void add(SpanProbe probe) {
180194
spanProbeCount++;
181195
}
182196

197+
void add(DebuggerProbe probe) {
198+
if (debuggerProbeCount >= MAX_ALLOWED_DEBUGGER_PROBES) {
199+
LOGGER.debug("Max allowed debugger probes reached, ignoring new probe: {}", probe);
200+
return;
201+
}
202+
definitions.add(probe);
203+
debuggerProbeCount++;
204+
}
205+
183206
void add(SpanDecorationProbe probe) {
184207
if (spanDecorationProbeCount >= MAX_ALLOWED_SPAN_DECORATION_PROBES) {
185208
LOGGER.debug("Max allowed span decoration probes reached, ignoring new probe: {}", probe);
@@ -197,6 +220,8 @@ void addAll(Collection<ProbeDefinition> newDefinitions) {
197220
add((LogProbe) definition);
198221
} else if (definition instanceof SpanProbe) {
199222
add((SpanProbe) definition);
223+
} else if (definition instanceof DebuggerProbe) {
224+
add((DebuggerProbe) definition);
200225
} else if (definition instanceof SpanDecorationProbe) {
201226
add((SpanDecorationProbe) definition);
202227
}

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

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.datadog.debugger.instrumentation.DiagnosticMessage;
77
import com.datadog.debugger.instrumentation.InstrumentationResult;
88
import com.datadog.debugger.instrumentation.MethodInfo;
9+
import com.datadog.debugger.probe.DebuggerProbe;
910
import com.datadog.debugger.probe.ExceptionProbe;
1011
import com.datadog.debugger.probe.ForceMethodInstrumentation;
1112
import com.datadog.debugger.probe.LogProbe;
@@ -77,7 +78,12 @@ public class DebuggerTransformer implements ClassFileTransformer {
7778
private static final String CANNOT_FIND_LINE = "No executable code was found at %s:L%s";
7879
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
7980
private static final List<Class<?>> PROBE_ORDER =
80-
Arrays.asList(MetricProbe.class, LogProbe.class, SpanDecorationProbe.class, SpanProbe.class);
81+
Arrays.asList(
82+
DebuggerProbe.class,
83+
MetricProbe.class,
84+
LogProbe.class,
85+
SpanDecorationProbe.class,
86+
SpanProbe.class);
8187
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
8288

8389
private final Config config;
@@ -212,7 +218,7 @@ private Map<Where, List<ProbeDefinition>> mergeLocations(
212218
Map<Where, List<ProbeDefinition>> mergedProbes = new HashMap<>();
213219
for (ProbeDefinition definition : definitions) {
214220
Where where = definition.getWhere();
215-
if (definition instanceof ExceptionProbe) {
221+
if (definition instanceof ForceMethodInstrumentation) {
216222
// normalize where for line => to precise method location
217223
where = Where.convertLineToMethod(definition.getWhere(), classFileLines);
218224
}
@@ -411,7 +417,7 @@ private void verifyByteCode(String classFilePath, byte[] classFile) {
411417
if (!result.isEmpty()) {
412418
log.warn("Verification of instrumented class {} failed", classFilePath);
413419
log.debug("Verify result: {}", stringWriter);
414-
throw new RuntimeException("Generated bydecode is invalid for " + classFilePath);
420+
throw new RuntimeException("Generated bytecode is invalid for " + classFilePath);
415421
}
416422
}
417423

0 commit comments

Comments
 (0)