Skip to content

Commit a2f3c7a

Browse files
authored
Make SymbolDB stand alone (#10064)
To be able to subscribe to symbol DB without enabling DI. Starting Symbol DB is still control from the backend.
1 parent b690a79 commit a2f3c7a

File tree

2 files changed

+64
-29
lines changed

2 files changed

+64
-29
lines changed

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

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public class DebuggerAgent {
7070
static final AtomicBoolean exceptionReplayEnabled = new AtomicBoolean();
7171
static final AtomicBoolean codeOriginEnabled = new AtomicBoolean();
7272
static final AtomicBoolean distributedDebuggerEnabled = new AtomicBoolean();
73+
static final AtomicBoolean symDBEnabled = new AtomicBoolean();
7374
private static ClassesToRetransformFinder classesToRetransformFinder;
7475

7576
public static synchronized void run(
@@ -89,10 +90,14 @@ public static synchronized void run(
8990
if (config.isDynamicInstrumentationEnabled()) {
9091
startDynamicInstrumentation(config);
9192
startCodeOriginForSpans(config);
93+
startSymbolDatabase(config);
9294
if (config.getDynamicInstrumentationInstrumentTheWorld() != null) {
9395
setupInstrumentTheWorldTransformer(config, instrumentation, sink);
9496
}
9597
}
98+
if (config.isSymbolDatabaseEnabled()) {
99+
startSymbolDatabase(config);
100+
}
96101
try {
97102
/*
98103
Note: shutdown hooks are tricky because JVM holds reference for them forever preventing
@@ -165,24 +170,7 @@ public static void startDynamicInstrumentation(Config config) {
165170
return;
166171
}
167172
if (configurationPoller != null) {
168-
if (config.isSymbolDatabaseEnabled()) {
169-
initClassNameFilter();
170-
List<ScopeFilter> scopeFilters =
171-
Arrays.asList(new AvroFilter(), new ProtoFilter(), new WireFilter());
172-
SymbolAggregator symbolAggregator =
173-
new SymbolAggregator(
174-
classNameFilter,
175-
scopeFilters,
176-
sink.getSymbolSink(),
177-
config.getSymbolDatabaseFlushThreshold());
178-
symbolAggregator.start();
179-
symDBEnablement =
180-
new SymDBEnablement(instrumentation, config, symbolAggregator, classNameFilter);
181-
if (config.isSymbolDatabaseForceUpload()) {
182-
symDBEnablement.startSymbolExtraction();
183-
}
184-
}
185-
subscribeConfigurationPoller(config, configurationUpdater, symDBEnablement);
173+
subscribeLiveDebugging(config, configurationUpdater);
186174
} else {
187175
LOGGER.debug("No configuration poller available from SharedCommunicationObjects");
188176
}
@@ -205,6 +193,62 @@ public static void stopDynamicInstrumentation() {
205193
}
206194
}
207195

196+
private static void subscribeLiveDebugging(
197+
Config config, ConfigurationUpdater configurationUpdater) {
198+
LOGGER.debug("Subscribing to Live Debugging...");
199+
configurationPoller.addListener(
200+
Product.LIVE_DEBUGGING, new DebuggerProductChangesListener(config, configurationUpdater));
201+
}
202+
203+
public static void startSymbolDatabase(Config config) {
204+
if (!symDBEnabled.compareAndSet(false, true)) {
205+
return;
206+
}
207+
LOGGER.debug("Starting Symbol Database");
208+
commonInit(config);
209+
initClassNameFilter();
210+
List<ScopeFilter> scopeFilters =
211+
Arrays.asList(new AvroFilter(), new ProtoFilter(), new WireFilter());
212+
SymbolAggregator symbolAggregator =
213+
new SymbolAggregator(
214+
classNameFilter,
215+
scopeFilters,
216+
sink.getSymbolSink(),
217+
config.getSymbolDatabaseFlushThreshold());
218+
symbolAggregator.start();
219+
symDBEnablement =
220+
new SymDBEnablement(instrumentation, config, symbolAggregator, classNameFilter);
221+
if (config.isSymbolDatabaseForceUpload()) {
222+
symDBEnablement.startSymbolExtraction();
223+
}
224+
subscribeSymDB(symDBEnablement);
225+
LOGGER.debug("Started Symbol Database");
226+
}
227+
228+
private static void subscribeSymDB(SymDBEnablement symDBEnablement) {
229+
LOGGER.debug("Subscribing to Symbol DB...");
230+
if (configurationPoller != null) {
231+
configurationPoller.addListener(Product.LIVE_DEBUGGING_SYMBOL_DB, symDBEnablement);
232+
} else {
233+
LOGGER.debug("No configuration poller available from SharedCommunicationObjects");
234+
}
235+
}
236+
237+
public static void stopSymbolDatabase() {
238+
if (!symDBEnabled.compareAndSet(true, false)) {
239+
return;
240+
}
241+
LOGGER.info("Stopping Symbol Database");
242+
if (configurationPoller != null) {
243+
configurationPoller.removeListeners(Product.LIVE_DEBUGGING_SYMBOL_DB);
244+
}
245+
SymDBEnablement localSymDBEnablement = symDBEnablement;
246+
if (localSymDBEnablement != null) {
247+
localSymDBEnablement.stopSymbolExtraction();
248+
symDBEnablement = null;
249+
}
250+
}
251+
208252
public static void startExceptionReplay(Config config) {
209253
if (!exceptionReplayEnabled.compareAndSet(false, true)) {
210254
return;
@@ -369,17 +413,6 @@ private static void setupSourceFileTracking(
369413
instrumentation.addTransformer(sourceFileTrackingTransformer);
370414
}
371415

372-
private static void subscribeConfigurationPoller(
373-
Config config, ConfigurationUpdater configurationUpdater, SymDBEnablement symDBEnablement) {
374-
LOGGER.debug("Subscribing to Live Debugging...");
375-
configurationPoller.addListener(
376-
Product.LIVE_DEBUGGING, new DebuggerProductChangesListener(config, configurationUpdater));
377-
if (symDBEnablement != null && !config.isSymbolDatabaseForceUpload()) {
378-
LOGGER.debug("Subscribing to Symbol DB...");
379-
configurationPoller.addListener(Product.LIVE_DEBUGGING_SYMBOL_DB, symDBEnablement);
380-
}
381-
}
382-
383416
private static void unsubscribeConfigurationPoller() {
384417
if (configurationPoller != null) {
385418
configurationPoller.removeListeners(Product.LIVE_DEBUGGING);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
99
import datadog.communication.ddagent.SharedCommunicationObjects;
10+
import datadog.remoteconfig.ConfigurationPoller;
1011
import datadog.trace.api.Config;
1112
import datadog.trace.api.debugger.DebuggerConfigUpdate;
1213
import java.lang.instrument.Instrumentation;
@@ -17,6 +18,7 @@ class DefaultDebuggerConfigUpdaterTest {
1718
@Test
1819
public void enableDisable() {
1920
SharedCommunicationObjects sco = mock(SharedCommunicationObjects.class);
21+
when(sco.configurationPoller(null)).thenReturn(mock(ConfigurationPoller.class));
2022
when(sco.featuresDiscovery(any())).thenReturn(mock(DDAgentFeaturesDiscovery.class));
2123
DebuggerAgent.run(Config.get(), mock(Instrumentation.class), sco);
2224
DefaultDebuggerConfigUpdater productConfigUpdater =

0 commit comments

Comments
 (0)