|
4 | 4 | import static java.util.Comparator.reverseOrder;
|
5 | 5 | import static java.util.Locale.ROOT;
|
6 | 6 |
|
7 |
| -import com.sun.management.HotSpotDiagnosticMXBean; |
| 7 | +import com.datadoghq.profiler.JVMAccess; |
8 | 8 | import datadog.trace.api.Platform;
|
| 9 | +import datadog.trace.api.config.ProfilingConfig; |
| 10 | +import datadog.trace.bootstrap.config.provider.ConfigProvider; |
9 | 11 | import datadog.trace.util.PidHelper;
|
10 | 12 | import java.io.BufferedWriter;
|
11 | 13 | import java.io.IOException;
|
12 | 14 | import java.io.InputStream;
|
13 |
| -import java.lang.management.ManagementFactory; |
14 | 15 | import java.net.URL;
|
15 | 16 | import java.nio.file.Files;
|
16 | 17 | import java.nio.file.Path;
|
|
20 | 21 | import org.slf4j.Logger;
|
21 | 22 | import org.slf4j.LoggerFactory;
|
22 | 23 |
|
23 |
| -public final class ScriptInitializer { |
24 |
| - static final Logger LOG = LoggerFactory.getLogger(ScriptInitializer.class); |
| 24 | +public final class Initializer { |
| 25 | + static final Logger LOG = LoggerFactory.getLogger(Initializer.class); |
25 | 26 | static final String PID_PREFIX = "_pid";
|
26 | 27 | static final String RWXRWXRWX = "rwxrwxrwx";
|
27 | 28 | static final String R_XR_XR_X = "r-xr-xr-x";
|
28 | 29 |
|
29 | 30 | public static void initialize() {
|
30 |
| - // this is HotSpot specific implementation (eg. will not work for IBM J9) |
31 |
| - HotSpotDiagnosticMXBean diagBean = |
32 |
| - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); |
| 31 | + ConfigProvider cfgProvider = ConfigProvider.getInstance(); |
| 32 | + String scratchDir = cfgProvider.getString(ProfilingConfig.PROFILING_DATADOG_PROFILER_SCRATCH); |
33 | 33 |
|
34 |
| - initializeCrashUploader(diagBean); |
35 |
| - initializeOOMENotifier(diagBean); |
| 34 | + JVMAccess jvmAccess = |
| 35 | + new JVMAccess( |
| 36 | + null, |
| 37 | + scratchDir, |
| 38 | + throwable -> { |
| 39 | + logInitializationError( |
| 40 | + "Unexpected exception while initializing JVMAccess", throwable); |
| 41 | + }); |
| 42 | + |
| 43 | + JVMAccess.Flags flags = jvmAccess.flags(); |
| 44 | + |
| 45 | + // // this is HotSpot specific implementation (eg. will not work for IBM J9) |
| 46 | + // HotSpotDiagnosticMXBean diagBean = |
| 47 | + // ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); |
| 48 | + |
| 49 | + initializeCrashUploader(flags); |
| 50 | + initializeOOMENotifier(flags); |
36 | 51 | }
|
37 | 52 |
|
38 | 53 | static InputStream getCrashUploaderTemplate() {
|
@@ -130,28 +145,75 @@ private static String getBaseName(Path path) {
|
130 | 145 | * `dd_crash_uploader.bat` and the script does not exist it will be created and prefilled with
|
131 | 146 | * code ensuring the error log upload will be triggered on JVM crash.
|
132 | 147 | */
|
133 |
| - private static void initializeCrashUploader(HotSpotDiagnosticMXBean diagBean) { |
| 148 | + private static void initializeCrashUploader(JVMAccess.Flags flags) { |
134 | 149 | try {
|
135 |
| - String onErrorVal = diagBean.getVMOption("OnError").getValue(); |
136 |
| - String onErrorFile = diagBean.getVMOption("ErrorFile").getValue(); |
137 |
| - CrashUploaderScriptInitializer.initialize(onErrorVal, onErrorFile); |
| 150 | + String onErrorVal = flags.getStringFlag("OnError"); |
| 151 | + String onErrorFile = flags.getStringFlag("ErrorFile"); |
| 152 | + |
| 153 | + String uploadScript = getScript("dd_crash_uploader"); |
| 154 | + if (onErrorVal == null || onErrorVal.isEmpty()) { |
| 155 | + onErrorVal = uploadScript; |
| 156 | + } else if (!onErrorVal.contains("dd_crash_uploader")) { |
| 157 | + // we can chain scripts so let's preserve the original value in addition to our crash |
| 158 | + // uploader |
| 159 | + onErrorVal = uploadScript + "; " + onErrorVal; |
| 160 | + } |
| 161 | + |
| 162 | + // set the JVM flag |
| 163 | + flags.setStringFlag("OnError", onErrorVal); |
| 164 | + if (LOG.isDebugEnabled()) { |
| 165 | + String currentVal = flags.getStringFlag("OnError"); |
| 166 | + if (!currentVal.equals(uploadScript)) { |
| 167 | + LOG.debug("Unable to set OnError flag to {}. Crash-tracking may not work.", currentVal); |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + CrashUploaderScriptInitializer.initialize(uploadScript, onErrorFile); |
138 | 172 | } catch (Throwable t) {
|
139 | 173 | logInitializationError(
|
140 | 174 | "Unexpected exception while creating custom crash upload script. Crash tracking will not work properly.",
|
141 | 175 | t);
|
142 | 176 | }
|
143 | 177 | }
|
144 | 178 |
|
145 |
| - private static void initializeOOMENotifier(HotSpotDiagnosticMXBean diagBean) { |
| 179 | + private static void initializeOOMENotifier(JVMAccess.Flags flags) { |
146 | 180 | try {
|
147 |
| - String onOutOfMemoryVal = diagBean.getVMOption("OnOutOfMemoryError").getValue(); |
148 |
| - OOMENotifierScriptInitializer.initialize(onOutOfMemoryVal); |
| 181 | + String onOutOfMemoryVal = flags.getStringFlag("OnOutOfMemoryError"); |
| 182 | + String notifierScript = getScript("dd_oome_notifier"); |
| 183 | + |
| 184 | + if (onOutOfMemoryVal == null || onOutOfMemoryVal.isEmpty()) { |
| 185 | + onOutOfMemoryVal = notifierScript; |
| 186 | + } else if (!onOutOfMemoryVal.contains("dd_oome_notifier")) { |
| 187 | + // we can chain scripts so let's preserve the original value in addition to our oome tracker |
| 188 | + onOutOfMemoryVal = notifierScript + "; " + onOutOfMemoryVal; |
| 189 | + } |
| 190 | + |
| 191 | + // set the JVM flag |
| 192 | + flags.setStringFlag("OnOutOfMemoryError", onOutOfMemoryVal); |
| 193 | + if (LOG.isDebugEnabled()) { |
| 194 | + String currentVal = flags.getStringFlag("OnOutOfMemoryError"); |
| 195 | + if (!currentVal.equals(onOutOfMemoryVal)) { |
| 196 | + LOG.debug( |
| 197 | + "Unable to set OnOutOfMemoryError flag to {}. OOME tracking may not work.", |
| 198 | + currentVal); |
| 199 | + } |
| 200 | + } |
| 201 | + |
| 202 | + OOMENotifierScriptInitializer.initialize(notifierScript); |
149 | 203 | } catch (Throwable t) {
|
150 | 204 | logInitializationError(
|
151 | 205 | "Unexpected exception while initializing OOME notifier. OOMEs will not be tracked.", t);
|
152 | 206 | }
|
153 | 207 | }
|
154 | 208 |
|
| 209 | + private static String getScript(String scriptName) { |
| 210 | + return System.getProperty("java.io.tmpdir") + "/" + getScriptFileName(scriptName) + " %p"; |
| 211 | + } |
| 212 | + |
| 213 | + private static String getScriptFileName(String scriptName) { |
| 214 | + return scriptName + "." + (Platform.isWindows() ? "bat" : "sh"); |
| 215 | + } |
| 216 | + |
155 | 217 | private static void logInitializationError(String msg, Throwable t) {
|
156 | 218 | if (LOG.isDebugEnabled()) {
|
157 | 219 | LOG.warn("{}", msg, t);
|
|
0 commit comments