Skip to content

Commit dceca28

Browse files
authored
Add In-Product Enablement (#8461)
Introduce the ability to start and stop Debugger features: - Dynamic Instrumentation - Exception Replay - Code Origin - Distributed Debugger dynamically based on RemoteConfig record: APM_TRACING DebuggerAgent is now run every time at startup to have the base of some feature ready and be able to start the minimum required foe each feature. Ability to stop also the feature at any time to uninstall probes. Add smoke tests
1 parent be03ce5 commit dceca28

File tree

17 files changed

+630
-131
lines changed

17 files changed

+630
-131
lines changed

.circleci/config.continue.yml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ instrumentation_modules: &instrumentation_modules "dd-java-agent/instrumentation
3636
debugger_modules: &debugger_modules "dd-java-agent/agent-debugger|dd-java-agent/agent-bootstrap|dd-java-agent/agent-builder|internal-api|communication|dd-trace-core"
3737
profiling_modules: &profiling_modules "dd-java-agent/agent-profiling"
3838

39-
default_system_tests_commit: &default_system_tests_commit 0509dbd094c9cbf15f58db96f62276a0adff7efa
39+
default_system_tests_commit: &default_system_tests_commit 6980534f333b3f7a35d83df2230f00f4e26642f5
4040

4141
parameters:
4242
nightly:

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/Agent.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ private enum AgentFeature {
9696
CIVISIBILITY_AGENTLESS(CiVisibilityConfig.CIVISIBILITY_AGENTLESS_ENABLED, false),
9797
USM(UsmConfig.USM_ENABLED, false),
9898
TELEMETRY(GeneralConfig.TELEMETRY_ENABLED, true),
99-
DEBUGGER(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED, false),
100-
EXCEPTION_DEBUGGING(DebuggerConfig.EXCEPTION_REPLAY_ENABLED, false),
101-
SPAN_ORIGIN(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED, false),
99+
DYNAMIC_INSTRUMENTATION(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED, false),
100+
EXCEPTION_REPLAY(DebuggerConfig.EXCEPTION_REPLAY_ENABLED, false),
101+
CODE_ORIGIN(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED, false),
102102
DATA_JOBS(GeneralConfig.DATA_JOBS_ENABLED, false),
103103
AGENTLESS_LOG_SUBMISSION(GeneralConfig.AGENTLESS_LOG_SUBMISSION_ENABLED, false);
104104

@@ -149,9 +149,10 @@ public boolean isEnabledByDefault() {
149149
private static boolean ciVisibilityEnabled = false;
150150
private static boolean usmEnabled = false;
151151
private static boolean telemetryEnabled = true;
152-
private static boolean debuggerEnabled = false;
153-
private static boolean exceptionDebuggingEnabled = false;
154-
private static boolean spanOriginEnabled = false;
152+
private static boolean dynamicInstrumentationEnabled = false;
153+
private static boolean exceptionReplayEnabled = false;
154+
private static boolean codeOriginEnabled = false;
155+
private static boolean distributedDebuggerEnabled = false;
155156
private static boolean agentlessLogSubmissionEnabled = false;
156157

157158
/**
@@ -261,9 +262,9 @@ public static void start(
261262
|| isFeatureEnabled(AgentFeature.DEPRECATED_REMOTE_CONFIG);
262263
cwsEnabled = isFeatureEnabled(AgentFeature.CWS);
263264
telemetryEnabled = isFeatureEnabled(AgentFeature.TELEMETRY);
264-
debuggerEnabled = isFeatureEnabled(AgentFeature.DEBUGGER);
265-
exceptionDebuggingEnabled = isFeatureEnabled(AgentFeature.EXCEPTION_DEBUGGING);
266-
spanOriginEnabled = isFeatureEnabled(AgentFeature.SPAN_ORIGIN);
265+
dynamicInstrumentationEnabled = isFeatureEnabled(AgentFeature.DYNAMIC_INSTRUMENTATION);
266+
exceptionReplayEnabled = isFeatureEnabled(AgentFeature.EXCEPTION_REPLAY);
267+
codeOriginEnabled = isFeatureEnabled(AgentFeature.CODE_ORIGIN);
267268
agentlessLogSubmissionEnabled = isFeatureEnabled(AgentFeature.AGENTLESS_LOG_SUBMISSION);
268269

269270
if (profilingEnabled) {
@@ -1114,7 +1115,10 @@ private static void shutdownProfilingAgent(final boolean sync) {
11141115
}
11151116

11161117
private static void maybeStartDebugger(Instrumentation inst, Class<?> scoClass, Object sco) {
1117-
if (!debuggerEnabled && !exceptionDebuggingEnabled && !spanOriginEnabled) {
1118+
if (isExplicitlyDisabled(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED)
1119+
&& isExplicitlyDisabled(DebuggerConfig.EXCEPTION_REPLAY_ENABLED)
1120+
&& isExplicitlyDisabled(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED)
1121+
&& isExplicitlyDisabled(DebuggerConfig.DISTRIBUTED_DEBUGGER_ENABLED)) {
11181122
return;
11191123
}
11201124
if (!remoteConfigEnabled) {
@@ -1124,6 +1128,11 @@ private static void maybeStartDebugger(Instrumentation inst, Class<?> scoClass,
11241128
startDebuggerAgent(inst, scoClass, sco);
11251129
}
11261130

1131+
private static boolean isExplicitlyDisabled(String booleanKey) {
1132+
return Config.get().configProvider().isSet(booleanKey)
1133+
&& !Config.get().configProvider().getBoolean(booleanKey);
1134+
}
1135+
11271136
private static synchronized void startDebuggerAgent(
11281137
Instrumentation inst, Class<?> scoClass, Object sco) {
11291138
StaticEventLogger.begin("Debugger");

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ public String tag() {
5050
public abstract String tag();
5151
}
5252

53+
public interface ProductConfigUpdater {
54+
void updateConfig(
55+
Boolean dynamicInstrumentationEnabled,
56+
Boolean exceptionReplayEnabled,
57+
Boolean codeOriginEnabled,
58+
Boolean liveDebuggingEnabled);
59+
60+
boolean isDynamicInstrumentationEnabled();
61+
62+
boolean isExceptionReplayEnabled();
63+
64+
boolean isCodeOriginEnabled();
65+
66+
boolean isDistributedDebuggerEnabled();
67+
}
68+
5369
public interface ProbeResolver {
5470
ProbeImplementation resolve(String encodedProbeId);
5571
}
@@ -103,6 +119,7 @@ public interface CodeOriginRecorder {
103119
String captureCodeOrigin(Method method, boolean entry, boolean instrument);
104120
}
105121

122+
private static volatile ProductConfigUpdater productConfigUpdater;
106123
private static volatile ProbeResolver probeResolver;
107124
private static volatile ClassFilter classFilter;
108125
private static volatile ClassNameFilter classNameFilter;
@@ -112,6 +129,10 @@ public interface CodeOriginRecorder {
112129
private static volatile ExceptionDebugger exceptionDebugger;
113130
private static volatile CodeOriginRecorder codeOriginRecorder;
114131

132+
public static void initProductConfigUpdater(ProductConfigUpdater productConfigUpdater) {
133+
DebuggerContext.productConfigUpdater = productConfigUpdater;
134+
}
135+
115136
public static void initProbeResolver(ProbeResolver probeResolver) {
116137
DebuggerContext.probeResolver = probeResolver;
117138
}
@@ -144,6 +165,59 @@ public static void initCodeOrigin(CodeOriginRecorder codeOriginRecorder) {
144165
DebuggerContext.codeOriginRecorder = codeOriginRecorder;
145166
}
146167

168+
public static void updateConfig(
169+
Boolean dynamicInstrumentationEnabled,
170+
Boolean exceptionReplayEnabled,
171+
Boolean codeOriginEnabled,
172+
Boolean liveDebuggingEnabled) {
173+
LOGGER.debug(
174+
"Updating config: dynamicInstrumentationEnabled: {}, exceptionReplayEnabled: {}, codeOriginEnabled: {}, liveDebuggingEnabled: {}",
175+
dynamicInstrumentationEnabled,
176+
exceptionReplayEnabled,
177+
codeOriginEnabled,
178+
liveDebuggingEnabled);
179+
ProductConfigUpdater updater = productConfigUpdater;
180+
if (updater != null) {
181+
updater.updateConfig(
182+
dynamicInstrumentationEnabled,
183+
exceptionReplayEnabled,
184+
codeOriginEnabled,
185+
liveDebuggingEnabled);
186+
}
187+
}
188+
189+
public static boolean isDynamicInstrumentationEnabled() {
190+
ProductConfigUpdater updater = productConfigUpdater;
191+
if (updater != null) {
192+
return updater.isDynamicInstrumentationEnabled();
193+
}
194+
return Config.get().isDynamicInstrumentationEnabled();
195+
}
196+
197+
public static boolean isExceptionReplayEnabled() {
198+
ProductConfigUpdater updater = productConfigUpdater;
199+
if (updater != null) {
200+
return updater.isExceptionReplayEnabled();
201+
}
202+
return Config.get().isDebuggerExceptionEnabled();
203+
}
204+
205+
public static boolean isCodeOriginEnabled() {
206+
ProductConfigUpdater updater = productConfigUpdater;
207+
if (updater != null) {
208+
return updater.isCodeOriginEnabled();
209+
}
210+
return Config.get().isDebuggerCodeOriginEnabled();
211+
}
212+
213+
public static boolean isDistributedDebuggerEnabled() {
214+
ProductConfigUpdater updater = productConfigUpdater;
215+
if (updater != null) {
216+
return updater.isDistributedDebuggerEnabled();
217+
}
218+
return Config.get().isDistributedDebuggerEnabled();
219+
}
220+
147221
/**
148222
* Returns the probe details based on the probe id provided. If no probe is found, try to
149223
* re-transform the class using the callingClass parameter No-op if no implementation available

0 commit comments

Comments
 (0)