Skip to content

Commit 70815cc

Browse files
committed
Add In-Product Enablement
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 Refactor common initialization to be done at least once either by dynamic Instrumentation, Exception Replay or Code Origin
1 parent 1c3133b commit 70815cc

File tree

17 files changed

+717
-162
lines changed

17 files changed

+717
-162
lines changed

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
@@ -101,9 +101,9 @@ private enum AgentFeature {
101101
CIVISIBILITY_AGENTLESS(CiVisibilityConfig.CIVISIBILITY_AGENTLESS_ENABLED, false),
102102
USM(UsmConfig.USM_ENABLED, false),
103103
TELEMETRY(GeneralConfig.TELEMETRY_ENABLED, true),
104-
DEBUGGER(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED, false),
105-
EXCEPTION_DEBUGGING(DebuggerConfig.EXCEPTION_REPLAY_ENABLED, false),
106-
SPAN_ORIGIN(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED, false),
104+
DYNAMIC_INSTRUMENTATION(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED, false),
105+
EXCEPTION_REPLAY(DebuggerConfig.EXCEPTION_REPLAY_ENABLED, false),
106+
CODE_ORIGIN(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED, false),
107107
DATA_JOBS(GeneralConfig.DATA_JOBS_ENABLED, false),
108108
AGENTLESS_LOG_SUBMISSION(GeneralConfig.AGENTLESS_LOG_SUBMISSION_ENABLED, false);
109109

@@ -154,9 +154,10 @@ public boolean isEnabledByDefault() {
154154
private static boolean ciVisibilityEnabled = false;
155155
private static boolean usmEnabled = false;
156156
private static boolean telemetryEnabled = true;
157-
private static boolean debuggerEnabled = false;
158-
private static boolean exceptionDebuggingEnabled = false;
159-
private static boolean spanOriginEnabled = false;
157+
private static boolean dynamicInstrumentationEnabled = false;
158+
private static boolean exceptionReplayEnabled = false;
159+
private static boolean codeOriginEnabled = false;
160+
private static boolean distributedDebuggerEnabled = false;
160161
private static boolean agentlessLogSubmissionEnabled = false;
161162

162163
/**
@@ -266,9 +267,9 @@ public static void start(
266267
|| isFeatureEnabled(AgentFeature.DEPRECATED_REMOTE_CONFIG);
267268
cwsEnabled = isFeatureEnabled(AgentFeature.CWS);
268269
telemetryEnabled = isFeatureEnabled(AgentFeature.TELEMETRY);
269-
debuggerEnabled = isFeatureEnabled(AgentFeature.DEBUGGER);
270-
exceptionDebuggingEnabled = isFeatureEnabled(AgentFeature.EXCEPTION_DEBUGGING);
271-
spanOriginEnabled = isFeatureEnabled(AgentFeature.SPAN_ORIGIN);
270+
dynamicInstrumentationEnabled = isFeatureEnabled(AgentFeature.DYNAMIC_INSTRUMENTATION);
271+
exceptionReplayEnabled = isFeatureEnabled(AgentFeature.EXCEPTION_REPLAY);
272+
codeOriginEnabled = isFeatureEnabled(AgentFeature.CODE_ORIGIN);
272273
agentlessLogSubmissionEnabled = isFeatureEnabled(AgentFeature.AGENTLESS_LOG_SUBMISSION);
273274

274275
if (profilingEnabled) {
@@ -1127,7 +1128,10 @@ private static void shutdownProfilingAgent(final boolean sync) {
11271128
}
11281129

11291130
private static void maybeStartDebugger(Instrumentation inst, Class<?> scoClass, Object sco) {
1130-
if (!debuggerEnabled && !exceptionDebuggingEnabled && !spanOriginEnabled) {
1131+
if (isExplicitlyDisabled(DebuggerConfig.DYNAMIC_INSTRUMENTATION_ENABLED)
1132+
&& isExplicitlyDisabled(DebuggerConfig.EXCEPTION_REPLAY_ENABLED)
1133+
&& isExplicitlyDisabled(TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED)
1134+
&& isExplicitlyDisabled(DebuggerConfig.DISTRIBUTED_DEBUGGER_ENABLED)) {
11311135
return;
11321136
}
11331137
if (!remoteConfigEnabled) {
@@ -1137,6 +1141,11 @@ private static void maybeStartDebugger(Instrumentation inst, Class<?> scoClass,
11371141
startDebuggerAgent(inst, scoClass, sco);
11381142
}
11391143

1144+
private static boolean isExplicitlyDisabled(String booleanKey) {
1145+
return Config.get().configProvider().isSet(booleanKey)
1146+
&& !Config.get().configProvider().getBoolean(booleanKey);
1147+
}
1148+
11401149
private static synchronized void startDebuggerAgent(
11411150
Instrumentation inst, Class<?> scoClass, Object sco) {
11421151
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)