Skip to content

Commit fe36e56

Browse files
committed
Report profiler initialization and configuration errors to telemetry
1 parent 9247ce3 commit fe36e56

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-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: 73 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,65 @@ private static String readPerfEventsParanoidSetting() {
244256
}
245257
return value;
246258
}
259+
260+
@Override
261+
public String toString() {
262+
return "{"
263+
+ "kind='"
264+
+ profilerKind()
265+
+ '\''
266+
+ ", uploadPeriod="
267+
+ uploadPeriod
268+
+ ", uploadTimeout="
269+
+ uploadTimeout
270+
+ ", uploadCompression='"
271+
+ uploadCompression
272+
+ '\''
273+
+ ", allocationProfilingEnabled="
274+
+ allocationProfilingEnabled
275+
+ ", heapProfilingEnabled="
276+
+ heapProfilingEnabled
277+
+ ", startForceFirst="
278+
+ startForceFirst
279+
+ ", templateOverride='"
280+
+ templateOverride
281+
+ '\''
282+
+ ", exceptionSampleLimit="
283+
+ exceptionSampleLimit
284+
+ ", exceptionHistogramTopItems="
285+
+ exceptionHistogramTopItems
286+
+ ", exceptionHistogramMaxSize="
287+
+ exceptionHistogramMaxSize
288+
+ ", hotspotsEnabled="
289+
+ hotspotsEnabled
290+
+ ", endpointsEnabled="
291+
+ endpointsEnabled
292+
+ ", auxiliaryProfiler='"
293+
+ auxiliaryProfiler
294+
+ '\''
295+
+ ", perfEventsParanoid='"
296+
+ perfEventsParanoid
297+
+ '\''
298+
+ ", hasNativeStacks="
299+
+ hasNativeStacks
300+
+ ", seLinuxStatus='"
301+
+ seLinuxStatus
302+
+ '\''
303+
+ ", serviceInstrumentationType='"
304+
+ serviceInstrumentationType
305+
+ '\''
306+
+ ", serviceInjection='"
307+
+ serviceInjection
308+
+ '\''
309+
+ ", ddprofUnavailableReason='"
310+
+ ddprofUnavailableReason
311+
+ '\''
312+
+ ", profilerActivationSetting="
313+
+ profilerActivationSetting
314+
+ ", stackDepth="
315+
+ stackDepth
316+
+ ", hasJfrStackDepthApplied="
317+
+ hasJfrStackDepthApplied
318+
+ '}';
319+
}
247320
}

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)