-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #79
- Loading branch information
Showing
6 changed files
with
186 additions
and
6 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
os/src/main/java/io/smallrye/common/os/GetAllProcessesInfoAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package io.smallrye.common.os; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.DirectoryStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.security.PrivilegedAction; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Scanner; | ||
import java.util.function.Predicate; | ||
import java.util.regex.Pattern; | ||
|
||
final class GetAllProcessesInfoAction implements PrivilegedAction<List<ProcessInfo>> { | ||
|
||
private final static Predicate<String> IS_NUMBER = Pattern.compile("\\d+").asPredicate(); | ||
|
||
@Override | ||
public List<ProcessInfo> run() { | ||
// The ProcessHandle API does not exist, so we have to rely on external processes to get this information | ||
switch (OS.current()) { | ||
case LINUX: | ||
return readLinuxProcesses(); | ||
case MAC: | ||
return readMacProcesses(); | ||
case WINDOWS: | ||
return readWindowsProcesses(); | ||
default: | ||
throw new UnsupportedOperationException( | ||
"Listing all processes is not supported in JDK 8 in " + OS.current().name()); | ||
} | ||
} | ||
|
||
private List<ProcessInfo> readLinuxProcesses() { | ||
List<ProcessInfo> processes = new ArrayList<>(); | ||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get("/proc"))) { | ||
for (Path procPath : stream) { | ||
String name = procPath.getFileName().toString(); | ||
if (IS_NUMBER.test(name)) { | ||
long pid = Long.parseLong(name); | ||
try (BufferedReader reader = Files | ||
.newBufferedReader(procPath.resolve("cmdline"), StandardCharsets.UTF_8)) { | ||
String line = reader.readLine(); | ||
if (line != null) { | ||
int idx = line.indexOf(0); | ||
String cmdLine = idx == -1 ? line : line.substring(0, idx); | ||
processes.add(new ProcessInfo(pid, cmdLine)); | ||
} | ||
} | ||
} | ||
} | ||
} catch (IOException ignored) { | ||
// ignore | ||
} | ||
return processes; | ||
} | ||
|
||
private List<ProcessInfo> readMacProcesses() { | ||
List<ProcessInfo> processes = new ArrayList<>(); | ||
java.lang.Process process = null; | ||
try { | ||
// PID CMD | ||
// 1 /usr/lib/systemd/systemd --switched-root --system --deserialize 34 | ||
process = new ProcessBuilder("ps", "-ax", "-o", "pid,cmd").start(); | ||
try (Scanner scanner = new Scanner(process.getInputStream())) { | ||
if (scanner.hasNextLine()) { | ||
scanner.nextLine(); | ||
} | ||
while (scanner.hasNextLine()) { | ||
String line = scanner.nextLine(); | ||
int separator = line.indexOf(" "); | ||
long pid = Long.parseLong(line.substring(0, separator)); | ||
String cmd = line.substring(separator + 1); | ||
processes.add(new ProcessInfo(pid,cmd)); | ||
} | ||
} | ||
} catch (IOException e) { | ||
// ignored | ||
} finally { | ||
if (process != null) { | ||
process.destroy(); | ||
} | ||
} | ||
return processes; | ||
} | ||
|
||
private List<ProcessInfo> readWindowsProcesses() { | ||
List<ProcessInfo> processes = new ArrayList<>(); | ||
java.lang.Process process = null; | ||
try { | ||
process = new ProcessBuilder("tasklist.exe", "/fo", "csv", "/nh").start(); | ||
Scanner sc = new Scanner(process.getInputStream()); | ||
// Skip first line | ||
if (sc.hasNextLine()) { | ||
sc.nextLine(); | ||
} | ||
while (sc.hasNextLine()) { | ||
String line = sc.nextLine(); | ||
String[] parts = line.split(","); | ||
String cmdLine = parts[0].substring(1).replaceFirst(".$", ""); | ||
long pid = Long.parseLong(parts[1].substring(1).replaceFirst(".$", "")); | ||
processes.add(new ProcessInfo(pid, cmdLine)); | ||
} | ||
} catch (IOException e) { | ||
// ignored | ||
} finally { | ||
if (process != null) { | ||
process.destroy(); | ||
} | ||
} | ||
return processes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,19 +20,19 @@ | |
|
||
import static java.security.AccessController.doPrivileged; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* Utilities for getting information about the current process. | ||
* | ||
* @author <a href="mailto:[email protected]">David M. Lloyd</a> | ||
*/ | ||
public final class Process { | ||
private static final long processId; | ||
private static final String processName; | ||
private static final ProcessInfo currentProcess; | ||
|
||
static { | ||
Object[] array = doPrivileged(new GetProcessInfoAction()); | ||
processId = (Long) array[0]; | ||
processName = (String) array[1]; | ||
currentProcess = new ProcessInfo((Long) array[0], (String) array[1]); | ||
} | ||
|
||
private Process() { | ||
|
@@ -44,7 +44,7 @@ private Process() { | |
* @return the process name (not {@code null}) | ||
*/ | ||
public static String getProcessName() { | ||
return processName; | ||
return currentProcess.getCommand(); | ||
} | ||
|
||
/** | ||
|
@@ -54,6 +54,25 @@ public static String getProcessName() { | |
* @return the ID of this process, or -1 if it cannot be determined | ||
*/ | ||
public static long getProcessId() { | ||
return processId; | ||
return currentProcess.getId(); | ||
} | ||
|
||
/** | ||
* Returns information about the current process | ||
* | ||
* @return the current process | ||
*/ | ||
public static ProcessInfo getCurrentProcess() { | ||
return currentProcess; | ||
} | ||
|
||
/** | ||
* Returns all the running processes. | ||
* | ||
* @return a list of all the running processes. May throw an exception if running on an unsupported JDK | ||
* @throws UnsupportedOperationException if running on JDK 8 | ||
*/ | ||
public static List<ProcessInfo> getAllProcesses() { | ||
return doPrivileged(new GetAllProcessesInfoAction()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.smallrye.common.os; | ||
|
||
/** | ||
* Returns information about a Process | ||
*/ | ||
public class ProcessInfo { | ||
private final long id; | ||
private final String command; | ||
|
||
public ProcessInfo(long id, String command) { | ||
this.id = id; | ||
this.command = command; | ||
} | ||
|
||
public long getId() { | ||
return id; | ||
} | ||
|
||
public String getCommand() { | ||
return command; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
os/src/main/java9/io/smallrye/common/os/GetAllProcessesInfoAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.smallrye.common.os; | ||
|
||
import java.security.PrivilegedAction; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
final class GetAllProcessesInfoAction implements PrivilegedAction<List<ProcessInfo>> { | ||
|
||
@Override | ||
public List<ProcessInfo> run() { | ||
return ProcessHandle.allProcesses() | ||
.map(processHandle -> new ProcessInfo(processHandle.pid(), processHandle.info().command().orElse(null))) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters