Skip to content

Commit 020dc0d

Browse files
MattAlpjbachorikbric3
authored
Read hsperfdata for Java PIDs if jvmstat is unavailable (#8792)
* Read hsperfdata for Java PIDs if jvmstat is unavailable * Add equivalent to JDK os::get_temp_directory() for clean-room jvmstat impl. * Add a comment documenting how JVM processes are enumerated Co-authored-by: Jaroslav Bachorik <[email protected]> * Remove unnecessary defensive path separator Co-authored-by: Brice Dutheil <[email protected]> * Spotless --------- Co-authored-by: Jaroslav Bachorik <[email protected]> Co-authored-by: Brice Dutheil <[email protected]>
1 parent 5d679e6 commit 020dc0d

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

internal-api/src/main/java/datadog/trace/util/PidHelper.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
import java.io.IOException;
99
import java.io.InputStreamReader;
1010
import java.lang.management.ManagementFactory;
11+
import java.nio.file.Files;
12+
import java.nio.file.Path;
13+
import java.nio.file.Paths;
1114
import java.util.Collections;
1215
import java.util.Set;
1316
import java.util.concurrent.CompletableFuture;
1417
import java.util.concurrent.TimeUnit;
1518
import java.util.function.Supplier;
19+
import java.util.stream.Collectors;
20+
import java.util.stream.Stream;
1621
import org.slf4j.Logger;
1722
import org.slf4j.LoggerFactory;
1823

@@ -64,12 +69,48 @@ private static String findPid() {
6469
return pid;
6570
}
6671

72+
private static String getOSTempDir() {
73+
// See
74+
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha#remarks
75+
// and
76+
// the JDK OS-specific implementations of os::get_temp_directory(), i.e.
77+
// https://github.com/openjdk/jdk/blob/f50bd0d9ec65a6b9596805d0131aaefc1bb913f3/src/hotspot/os/bsd/os_bsd.cpp#L886-L904
78+
if (Platform.isLinux()) {
79+
return "/tmp/";
80+
} else if (Platform.isWindows()) {
81+
return Stream.of(System.getenv("TMP"), System.getenv("TEMP"), System.getenv("USERPROFILE"))
82+
.filter(String::isEmpty)
83+
.findFirst()
84+
.orElse("C:\\Windows");
85+
} else if (Platform.isMac()) {
86+
return System.getenv("TMPDIR");
87+
} else {
88+
return System.getProperty("java.io.tmpdir");
89+
}
90+
}
91+
6792
public static Set<String> getJavaPids() {
6893
// Attempt to use jvmstat directly, fall through to jps process fork strategy
6994
Set<String> directlyObtainedPids = JPSUtils.getVMPids();
7095
if (directlyObtainedPids != null) {
7196
return directlyObtainedPids;
7297
}
98+
99+
// Some JDKs don't have jvmstat available as a module, attempt to read from the hsperfdata
100+
// directory instead
101+
try (Stream<Path> stream =
102+
// Emulating the hotspot way to enumerate the JVM processes using the perfdata file
103+
// https://github.com/openjdk/jdk/blob/d7cb933b89839b692f5562aeeb92076cd25a99f6/src/hotspot/share/runtime/perfMemory.cpp#L244
104+
Files.list(Paths.get(getOSTempDir(), "hsperfdata_" + System.getProperty("user.name")))) {
105+
return stream
106+
.filter(file -> !Files.isDirectory(file))
107+
.map(Path::getFileName)
108+
.map(Path::toString)
109+
.collect(Collectors.toSet());
110+
} catch (IOException e) {
111+
log.debug("Unable to obtain Java PIDs via hsperfdata", e);
112+
}
113+
73114
// there is no supported Java API to achieve this
74115
// one could use sun.jvmstat.monitor.MonitoredHost but it is an internal API and can go away at
75116
// any time -

0 commit comments

Comments
 (0)