Skip to content

Commit feb6c69

Browse files
committed
[PROF-10633] Revisit and unify profiling settings
1 parent 969d21d commit feb6c69

7 files changed

Lines changed: 839 additions & 28 deletions

File tree

dd-java-agent/agent-profiling/profiling-controller-openjdk/src/main/java/com/datadog/profiling/controller/openjdk/OpenJdkController.java

Lines changed: 109 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717

1818
import static com.datadog.profiling.controller.ProfilingSupport.*;
1919
import static datadog.environment.JavaVirtualMachine.isJavaVersionAtLeast;
20+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_ALLOC_ENABLED;
21+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_CPU_ENABLED;
22+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_EXCEPTION_ENABLED;
2023
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_HISTOGRAM_ENABLED;
2124
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_HISTOGRAM_ENABLED_DEFAULT;
2225
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_HISTOGRAM_MODE;
2326
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_HISTOGRAM_MODE_DEFAULT;
27+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_LATENCY_ENABLED;
28+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_LIVEHEAP_ENABLED;
29+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_LIVEHEAP_ENABLED_DEFAULT;
2430
import static datadog.trace.api.config.ProfilingConfig.PROFILING_QUEUEING_TIME_ENABLED;
2531
import static datadog.trace.api.config.ProfilingConfig.PROFILING_QUEUEING_TIME_ENABLED_DEFAULT;
2632
import static datadog.trace.api.config.ProfilingConfig.PROFILING_QUEUEING_TIME_THRESHOLD_MILLIS;
@@ -192,14 +198,101 @@ public OpenJdkController(final ConfigProvider configProvider)
192198

193199
// Toggle settings from config
194200

195-
if (configProvider.getBoolean(
196-
ProfilingConfig.PROFILING_HEAP_ENABLED, ProfilingConfig.PROFILING_HEAP_ENABLED_DEFAULT)) {
197-
log.debug("Enabling OldObjectSample JFR event with the config.");
198-
recordingSettings.put("jdk.OldObjectSample#enabled", "true");
201+
// --- CPU profiling umbrella (profiling.cpu.enabled) ---
202+
Boolean cpuUmbrella = configProvider.getBoolean(PROFILING_CPU_ENABLED);
203+
if (cpuUmbrella != null) {
204+
if (cpuUmbrella) {
205+
// Re-enable the correct CPU sampling event for the current JDK
206+
if (JavaVirtualMachine.isJavaVersionAtLeast(25) && OperatingSystem.isLinux()) {
207+
enableEvent(recordingSettings, "jdk.CPUTimeSample", EXPLICITLY_ENABLED);
208+
enableEvent(recordingSettings, "jdk.CPUTimeSamplesLost", EXPLICITLY_ENABLED);
209+
} else {
210+
enableEvent(recordingSettings, "jdk.ExecutionSample", EXPLICITLY_ENABLED);
211+
}
212+
} else {
213+
disableEvent(recordingSettings, "jdk.ExecutionSample", EXPLICITLY_DISABLED);
214+
disableEvent(recordingSettings, "jdk.CPUTimeSample", EXPLICITLY_DISABLED);
215+
disableEvent(recordingSettings, "jdk.CPUTimeSamplesLost", EXPLICITLY_DISABLED);
216+
}
199217
}
200218

201-
if (configProvider.getBoolean(
202-
ProfilingConfig.PROFILING_ALLOCATION_ENABLED, isObjectAllocationSampleAvailable())) {
219+
// --- Latency profiling umbrella (profiling.latency.enabled) ---
220+
Boolean latencyUmbrella = configProvider.getBoolean(PROFILING_LATENCY_ENABLED);
221+
if (latencyUmbrella != null) {
222+
if (latencyUmbrella) {
223+
enableEvent(recordingSettings, "jdk.JavaMonitorEnter", EXPLICITLY_ENABLED);
224+
enableEvent(recordingSettings, "jdk.JavaMonitorWait", EXPLICITLY_ENABLED);
225+
enableEvent(recordingSettings, "jdk.JavaMonitorInflate", EXPLICITLY_ENABLED);
226+
enableEvent(recordingSettings, "jdk.FileRead", EXPLICITLY_ENABLED);
227+
if (isFileWriteDurationCorrect()) {
228+
enableEvent(recordingSettings, "jdk.FileWrite", EXPLICITLY_ENABLED);
229+
}
230+
enableEvent(recordingSettings, "jdk.SocketRead", EXPLICITLY_ENABLED);
231+
enableEvent(recordingSettings, "jdk.SocketWrite", EXPLICITLY_ENABLED);
232+
enableEvent(recordingSettings, "jdk.ThreadStart", EXPLICITLY_ENABLED);
233+
} else {
234+
disableEvent(recordingSettings, "jdk.JavaMonitorEnter", EXPLICITLY_DISABLED);
235+
disableEvent(recordingSettings, "jdk.JavaMonitorWait", EXPLICITLY_DISABLED);
236+
disableEvent(recordingSettings, "jdk.JavaMonitorInflate", EXPLICITLY_DISABLED);
237+
disableEvent(recordingSettings, "jdk.FileRead", EXPLICITLY_DISABLED);
238+
disableEvent(recordingSettings, "jdk.FileWrite", EXPLICITLY_DISABLED);
239+
disableEvent(recordingSettings, "jdk.SocketRead", EXPLICITLY_DISABLED);
240+
disableEvent(recordingSettings, "jdk.SocketWrite", EXPLICITLY_DISABLED);
241+
disableEvent(recordingSettings, "jdk.ThreadStart", EXPLICITLY_DISABLED);
242+
}
243+
}
244+
245+
// --- Live heap profiling (profiling.liveheap.enabled / profiling.heap.enabled) ---
246+
// profiling.heap.enabled (explicit JFR override) takes precedence over umbrella
247+
Boolean heapExplicit = configProvider.getBoolean(ProfilingConfig.PROFILING_HEAP_ENABLED);
248+
if (heapExplicit != null) {
249+
if (heapExplicit) {
250+
log.debug("Enabling OldObjectSample JFR event with the config.");
251+
recordingSettings.put("jdk.OldObjectSample#enabled", "true");
252+
} else {
253+
disableEvent(recordingSettings, "jdk.OldObjectSample", EXPLICITLY_DISABLED);
254+
}
255+
} else {
256+
// Umbrella defaults to true — all GA features enabled out of the box.
257+
// Use nullable check to distinguish explicit user setting from default.
258+
Boolean liveheapUmbrella = configProvider.getBoolean(PROFILING_LIVEHEAP_ENABLED);
259+
boolean liveheapEnabled =
260+
liveheapUmbrella != null ? liveheapUmbrella : PROFILING_LIVEHEAP_ENABLED_DEFAULT;
261+
if (liveheapEnabled) {
262+
// Enable liveheap on the best available backend.
263+
// ddprof handles it when: ddprof is overall active AND liveheap not explicitly disabled.
264+
boolean ddprofLiveheapExplicitlyDisabled =
265+
Boolean.FALSE.equals(
266+
configProvider.getBoolean(
267+
ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED,
268+
ProfilingConfig.PROFILING_DATADOG_PROFILER_MEMLEAK_ENABLED));
269+
boolean ddprofEnabled =
270+
configProvider.getBoolean(ProfilingConfig.PROFILING_DATADOG_PROFILER_ENABLED, false);
271+
if (ddprofEnabled && !ddprofLiveheapExplicitlyDisabled) {
272+
// ddprof will handle live heap; suppress JFR OldObjectSample to avoid redundant overhead
273+
disableEvent(
274+
recordingSettings, "jdk.OldObjectSample", "ddprof backend handles live heap");
275+
} else if (liveheapUmbrella != null || isOldObjectSampleAvailable()) {
276+
// Explicit umbrella=true: force-enable OldObjectSample (even on older JDKs).
277+
// Default (umbrella not set): only enable if OldObjectSample is inexpensive.
278+
recordingSettings.put("jdk.OldObjectSample#enabled", "true");
279+
}
280+
} else {
281+
disableEvent(recordingSettings, "jdk.OldObjectSample", EXPLICITLY_DISABLED);
282+
}
283+
}
284+
285+
// --- Allocation profiling (profiling.alloc.enabled / profiling.allocation.enabled) ---
286+
// Priority: profiling.allocation.enabled (JFR override) > profiling.alloc.enabled (umbrella)
287+
// > default (ObjectAllocationSample availability)
288+
Boolean allocationExplicit =
289+
configProvider.getBoolean(ProfilingConfig.PROFILING_ALLOCATION_ENABLED);
290+
Boolean allocationUmbrella = configProvider.getBoolean(PROFILING_ALLOC_ENABLED);
291+
boolean allocationEnabled =
292+
allocationExplicit != null
293+
? allocationExplicit
294+
: allocationUmbrella != null ? allocationUmbrella : isObjectAllocationSampleAvailable();
295+
if (allocationEnabled) {
203296
// jdk.ObjectAllocationSample is available and enabled by default
204297
if (!isObjectAllocationSampleAvailable()) {
205298
log.debug(
@@ -215,6 +308,16 @@ ProfilingConfig.PROFILING_ALLOCATION_ENABLED, isObjectAllocationSampleAvailable(
215308
}
216309
}
217310

311+
// --- Exception profiling umbrella (profiling.exception.enabled) ---
312+
Boolean exceptionUmbrella = configProvider.getBoolean(PROFILING_EXCEPTION_ENABLED);
313+
if (exceptionUmbrella != null) {
314+
if (exceptionUmbrella) {
315+
enableEvent(recordingSettings, "datadog.ExceptionSample", EXPLICITLY_ENABLED);
316+
} else {
317+
disableEvent(recordingSettings, "datadog.ExceptionSample", EXPLICITLY_DISABLED);
318+
}
319+
}
320+
218321
if (configProvider.getBoolean(
219322
ProfilingConfig.PROFILING_SMAP_COLLECTION_ENABLED,
220323
ProfilingConfig.PROFILING_SMAP_COLLECTION_ENABLED_DEFAULT)) {

0 commit comments

Comments
 (0)