Skip to content

Commit 03478c8

Browse files
authored
Report profiler initialization and configuration errors to telemetry (#8171)
* Report profiler initialization and configuration errors to telemetry * Spotless-less formatting
1 parent f768f02 commit 03478c8

File tree

6 files changed

+75
-7
lines changed

6 files changed

+75
-7
lines changed

dd-java-agent/agent-profiling/profiling-controller-ddprof/src/main/java/com/datadog/profiling/controller/ddprof/DatadogProfilerSettings.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ public void publish() {
4040
datadogProfiler.recordSetting(
4141
SSI_MECHANISM, profilerActivationSetting.ssiMechanism.name().toLowerCase());
4242
}
43+
44+
@Override
45+
protected String profilerKind() {
46+
return "datadog";
47+
}
4348
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,9 @@ public void publish() {
7575
.commit();
7676
}
7777
}
78+
79+
@Override
80+
protected String profilerKind() {
81+
return "jfr";
82+
}
7883
}

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.datadog.profiling.controller;
22

3+
import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY;
4+
35
import datadog.trace.api.Config;
46
import datadog.trace.api.Platform;
57
import datadog.trace.api.config.ProfilingConfig;
@@ -16,9 +18,13 @@
1618
import java.nio.file.Paths;
1719
import java.util.Objects;
1820
import java.util.concurrent.TimeUnit;
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
1923

2024
/** Capture the profiler config first and allow emitting the setting events per each recording. */
2125
public abstract class ProfilerSettingsSupport {
26+
private static final Logger logger = LoggerFactory.getLogger(ProfilerSettingsSupport.class);
27+
2228
protected static final class ProfilerActivationSetting {
2329
public enum Ssi {
2430
INJECTED_AGENT,
@@ -177,6 +183,10 @@ protected ProfilerSettingsSupport(
177183
// usually set via DD_INSTRUMENTATION_INSTALL_TYPE env var
178184
configProvider.getString("instrumentation.install.type");
179185
this.profilerActivationSetting = getProfilerActivation(configProvider);
186+
187+
logger.debug(
188+
SEND_TELEMETRY,
189+
"Profiler settings: " + this); // telemetry receiver does not recognize formatting
180190
}
181191

182192
private static String getServiceInjection(ConfigProvider configProvider) {
@@ -231,6 +241,8 @@ private static String getDefaultAuxiliaryProfiler() {
231241
/** To be defined in controller specific way. Eg. one could emit JFR events. */
232242
public abstract void publish();
233243

244+
protected abstract String profilerKind();
245+
234246
private static String readPerfEventsParanoidSetting() {
235247
String value = "unknown";
236248
if (Platform.isLinux()) {
@@ -244,4 +256,35 @@ private static String readPerfEventsParanoidSetting() {
244256
}
245257
return value;
246258
}
259+
260+
@Override
261+
public String toString() {
262+
// spotless:off
263+
return "{"
264+
+ "kind='" + profilerKind() + '\''
265+
+ ", uploadPeriod=" + uploadPeriod
266+
+ ", uploadTimeout=" + uploadTimeout
267+
+ ", uploadCompression='" + uploadCompression + '\''
268+
+ ", allocationProfilingEnabled=" + allocationProfilingEnabled
269+
+ ", heapProfilingEnabled=" + heapProfilingEnabled
270+
+ ", startForceFirst=" + startForceFirst
271+
+ ", templateOverride='" + templateOverride + '\''
272+
+ ", exceptionSampleLimit=" + exceptionSampleLimit
273+
+ ", exceptionHistogramTopItems=" + exceptionHistogramTopItems
274+
+ ", exceptionHistogramMaxSize=" + exceptionHistogramMaxSize
275+
+ ", hotspotsEnabled=" + hotspotsEnabled
276+
+ ", endpointsEnabled=" + endpointsEnabled
277+
+ ", auxiliaryProfiler='" + auxiliaryProfiler + '\''
278+
+ ", perfEventsParanoid='" + perfEventsParanoid + '\''
279+
+ ", hasNativeStacks=" + hasNativeStacks
280+
+ ", seLinuxStatus='" + seLinuxStatus + '\''
281+
+ ", serviceInstrumentationType='" + serviceInstrumentationType + '\''
282+
+ ", serviceInjection='" + serviceInjection + '\''
283+
+ ", ddprofUnavailableReason='" + ddprofUnavailableReason + '\''
284+
+ ", profilerActivationSetting=" + profilerActivationSetting
285+
+ ", stackDepth=" + stackDepth
286+
+ ", hasJfrStackDepthApplied=" + hasJfrStackDepthApplied
287+
+ '}';
288+
// spotless:on
289+
}
247290
}

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package com.datadog.profiling.controller;
1717

18+
import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY;
1819
import static datadog.trace.util.AgentThreadFactory.AgentThread.PROFILER_RECORDING_SCHEDULER;
1920

21+
import datadog.trace.api.Platform;
2022
import datadog.trace.api.profiling.ProfilingListenersRegistry;
2123
import datadog.trace.api.profiling.ProfilingSnapshot;
2224
import datadog.trace.api.profiling.RecordingData;
@@ -160,7 +162,15 @@ private void startProfilingRecording() {
160162
started = true;
161163
} catch (UnsupportedEnvironmentException unsupported) {
162164
log.warn(
163-
"Datadog Profiling was enabled on an unsupported JVM, will not profile application. See {} for more details about supported JVMs.",
165+
SEND_TELEMETRY,
166+
"Datadog Profiling was enabled on an unsupported JVM, will not profile application. "
167+
+ "(OS: {}, JVM: lang={}, runtime={}, vendor={}) See {} for more details about supported JVMs.",
168+
Platform.isLinux()
169+
? "Linux"
170+
: Platform.isWindows() ? "Windows" : Platform.isMac() ? "MacOS" : "Other",
171+
Platform.getLangVersion(),
172+
Platform.getRuntimeVersion(),
173+
Platform.getRuntimeVendor(),
164174
"https://docs.datadoghq.com/profiler/enabling/java/?tab=commandarguments#requirements");
165175
} catch (Throwable t) {
166176
if (t instanceof RuntimeException) {
@@ -171,6 +181,7 @@ private void startProfilingRecording() {
171181
if (msg != null && msg.contains("com.oracle.jrockit:type=FlightRecorder")) {
172182
// Yes, the commercial JFR is not enabled
173183
log.warn(
184+
SEND_TELEMETRY,
174185
"You're running Oracle JDK 8. Datadog Continuous Profiler for Java depends on Java Flight Recorder, which requires a paid license in Oracle JDK 8. If you have one, please add the following `java` command line args: ‘-XX:+UnlockCommercialFeatures -XX:+FlightRecorder’. Alternatively, you can use a different Java 8 distribution like OpenJDK, where Java Flight Recorder is free.");
175186
// Do not log the underlying exception
176187
t = null;
@@ -183,7 +194,7 @@ private void startProfilingRecording() {
183194
if (t instanceof IllegalStateException && "Shutdown in progress".equals(t.getMessage())) {
184195
log.debug("Shutdown in progress, cannot start profiling");
185196
} else {
186-
log.error("Fatal exception during profiling startup", t);
197+
log.error(SEND_TELEMETRY, "Fatal exception during profiling startup", t);
187198
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
188199
}
189200
}
@@ -267,7 +278,7 @@ public void snapshot(boolean onShutdown) {
267278
lastSnapshot = Instant.now();
268279
}
269280
} catch (final Exception e) {
270-
log.error("Exception in profiling thread, continuing", e);
281+
log.error(SEND_TELEMETRY, "Exception in profiling thread, continuing", e);
271282
} catch (final Throwable t) {
272283
/*
273284
Try to continue even after fatal exception. It seems to be useful to attempt to store profile when this happens.
@@ -276,7 +287,7 @@ public void snapshot(boolean onShutdown) {
276287
Another reason is that it may be bad to stop profiling if the rest of the app is continuing.
277288
*/
278289
try {
279-
log.error("Fatal exception in profiling thread, trying to continue", t);
290+
log.error(SEND_TELEMETRY, "Fatal exception in profiling thread, trying to continue", t);
280291
} catch (final Throwable t2) {
281292
// This should almost never happen and there is not much we can do here in cases like
282293
// OutOfMemoryError, so we will just ignore this.

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.datadog.profiling.controller;
22

3+
import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY;
4+
35
import datadog.trace.api.config.ProfilingConfig;
46
import datadog.trace.bootstrap.config.provider.ConfigProvider;
57
import datadog.trace.util.PidHelper;
@@ -239,6 +241,7 @@ private TempLocationManager() {
239241
ProfilingConfig.PROFILING_TEMP_DIR, ProfilingConfig.PROFILING_TEMP_DIR_DEFAULT));
240242
if (!Files.exists(configuredTempDir)) {
241243
log.warn(
244+
SEND_TELEMETRY,
242245
"Base temp directory, as defined in '"
243246
+ ProfilingConfig.PROFILING_TEMP_DIR
244247
+ "' does not exist: "
@@ -312,7 +315,7 @@ public Path getTempDir(Path subPath, boolean create) {
312315
rslt,
313316
PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------")));
314317
} catch (Exception e) {
315-
log.warn("Failed to create temp directory: {}", tempDir, e);
318+
log.warn(SEND_TELEMETRY, "Failed to create temp directory: {}", tempDir, e);
316319
throw new IllegalStateException("Failed to create temp directory: " + tempDir, e);
317320
}
318321
}

dd-java-agent/agent-profiling/src/main/java/com/datadog/profiling/agent/ProfilingAgent.java

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

33
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_FORCE_FIRST;
44
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_FORCE_FIRST_DEFAULT;
5+
import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY;
56
import static datadog.trace.util.AgentThreadFactory.AGENT_THREAD_GROUP;
67

78
import com.datadog.profiling.controller.ConfigurationException;
@@ -166,10 +167,10 @@ public static synchronized void run(
166167
}
167168
} catch (final UnsupportedEnvironmentException e) {
168169
log.warn(e.getMessage());
169-
log.debug("", e);
170+
log.debug(SEND_TELEMETRY, "Unsupported environment for Datadog profiler", e);
170171
} catch (final ConfigurationException e) {
171172
log.warn("Failed to initialize profiling agent! {}", e.getMessage());
172-
log.debug("Failed to initialize profiling agent!", e);
173+
log.debug(SEND_TELEMETRY, "Failed to initialize profiling agent!", e);
173174
}
174175
}
175176
}

0 commit comments

Comments
 (0)