diff --git a/build.xml b/build.xml index 989e58e..70c9b67 100644 --- a/build.xml +++ b/build.xml @@ -59,4 +59,17 @@ + + + + Java System Monitor]]> + Copyright © 2009 ThoughtWorks. All Rights Reserved.]]> + + + diff --git a/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java b/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java index 620c87e..d694731 100644 --- a/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java +++ b/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java @@ -3,13 +3,42 @@ import java.util.ArrayList; import java.util.Iterator; +/** + * This class provides the main API for JavaSysMon. + * You must instantiate this class in order to use it, + * but it stores no state, so there is zero overhead to + * instantiating it as many times as you like, and + * hence no need to cache it. + *

+ * When instantiated for the first time, JavaSysMon + * will discover which operating system it is running on + * and attempt to load the appropriate OS-specific + * extensions. If JavaSysMon doesn't support the OS + * you're running on, all calls to the API will return + * null or zero values. Probably the best one to test is + * osName. + *

+ * You can run JavaSysMon directly as a jar file, using + * the command "java -jar javasysmon.jar", in which case + * it will display output similar to the UNIX "top" + * command. You can optionally specify a process id as an + * argument, in which case JavaSysMon will attempt to + * kill the process. + * + * @author Jez Humble + */ public class JavaSysMon implements Monitor { private static Monitor monitor = null; private static ArrayList supported = new ArrayList(); - static void setMonitor(Monitor myMonitor) { - if (monitor == null) { + /** + * Allows you to register your own implementation of {@link Monitor}. + * + * @param myMonitor An implementation of the Monitor interface that all API calls will be delegated to + */ + public static void setMonitor(Monitor myMonitor) { + if (monitor == null || monitor instanceof NullMonitor) { monitor = myMonitor; } } @@ -26,6 +55,20 @@ static void addSupportedConfig(String config) { new NullMonitor(); // make sure the API never gives back a NPE } + /** + * Creates a new JavaSysMon object through which to access + * the JavaSysMon API. All necessary state is kept statically + * so there is zero overhead to instantiating this class. + */ + public JavaSysMon() {} + + /** + * This is the main entry point when running the jar directly. + * It prints out some system performance metrics and the process table + * in a format similar to the UNIX top command. Optionally you can + * specify a process id as an argument, in which case JavaSysMon + * will attempt to kill the process specified by that pid. + */ public static void main (String[] params) throws Exception { if (monitor instanceof NullMonitor) { System.err.println("Couldn't find an implementation for OS: " + System.getProperty("os.name")); @@ -65,46 +108,125 @@ private static String secsInDaysAndHours(long seconds) { // Following is the actual API + /** + * Get the operating system name. + * + * @return The operating system name. + */ public String osName() { return monitor.osName(); } + /** + * Get the number of CPU cores. + * + * @return The number of CPU cores. + */ public int numCpus() { return monitor.numCpus(); } + /** + * Get the CPU frequency in Hz + * + * @return the CPU frequency in Hz + */ public long cpuFrequencyInHz() { return monitor.cpuFrequencyInHz(); } + /** + * How long the system has been up in seconds. + * Doesn't generally include time that the system + * has been hibernating or asleep. + * + * @return The time the system has been up in seconds. + */ public long uptimeInSeconds() { return monitor.uptimeInSeconds(); } + /** + * Gets the pid of the process that is calling this method + * (assuming it is running in the same process). + * + * @return The pid of the process calling this method. + */ public int currentPid() { return monitor.currentPid(); } + /** + * Gets the total amount of time the CPU has spent in + * user mode, kernel mode, and idle. Can be used to + * calculate CPU usage. Simply take two data points, + * take the difference between these numbers, and + * calculate the percentage of time spent not idle. + * + * @return An object containing the amount of time the + * CPU has spent idle, in user mode and in kernel mode, + * in milliseconds. + */ public CpuTimes cpuTimes() { return monitor.cpuTimes(); } + /** + * Gets the physical memory installed, and the amount free. + * + * @return An object containing the amount of physical + * memory installed, and the amount free. + */ public MemoryStats physical() { return monitor.physical(); } + /** + * Gets the amount of swap available to the operating system, + * and the amount that is free. + * + * @return An object containing the amount of swap available + * to the system, and the amount free. + */ public MemoryStats swap() { return monitor.swap(); } + /** + * Get the current process table. This call returns an array of + * objects, each of which represents a single process. If you want + * the objects in a tree structure, use {@link #processTree} instead. + * + * @return An array of objects, each of which represents a process. + */ public ProcessInfo[] processTable() { return monitor.processTable(); } + /** + * Gets the current process table in the form of a process tree. + * The object returned is a top-level container which doesn't actually + * represent a process - its children are the top-level processes + * running in the system. This is necessary because some operating systems + * (Windows, for example) don't have a single top-level process (orphans + * are literally orphaned), and because the process table snapshot + * is not atomic. That means the process table thus returned can be + * internally inconsistent. + * + * @return The current process table in the form of a process tree. + */ public OsProcess processTree() { return OsProcess.createTree(monitor.processTable()); } + /** + * Attempts to kill the process identified by the integer id supplied. + * This will silently fail if you don't have the authority to kill + * that process. This method sends SIGTERM on the UNIX platform, + * and kills the process using TerminateProcess on Windows. + * + * @param pid The id of the process to kill + */ public void killProcess(int pid) { monitor.killProcess(pid); } @@ -113,6 +235,9 @@ public void killProcessTree(int pid, boolean descendantsOnly) { processTree().find(pid).killTree(descendantsOnly); } + /** + * Attempts to kill all the descendents of the currently running process. + */ public void infanticide() { killProcessTree(currentPid(), true); } diff --git a/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java b/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java index 22a12c7..266a836 100644 --- a/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java @@ -8,7 +8,7 @@ import java.util.regex.Pattern; // Network stats will come from /proc/net/dev; disk stats will be from /proc/diskstats -public class LinuxMonitor implements Monitor { +class LinuxMonitor implements Monitor { private static final Pattern TOTAL_MEMORY_PATTERN = Pattern.compile("MemTotal:\\s+(\\d+) kB", Pattern.MULTILINE); diff --git a/src/main/java/com/jezhumble/javasysmon/LinuxProcessInfoParser.java b/src/main/java/com/jezhumble/javasysmon/LinuxProcessInfoParser.java index 9485769..b4e6a66 100644 --- a/src/main/java/com/jezhumble/javasysmon/LinuxProcessInfoParser.java +++ b/src/main/java/com/jezhumble/javasysmon/LinuxProcessInfoParser.java @@ -4,7 +4,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class LinuxProcessInfoParser { +class LinuxProcessInfoParser { private final String stat; private final String status; private final String cmdline; diff --git a/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java b/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java index b2beccc..40ce43f 100644 --- a/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java @@ -1,6 +1,6 @@ package com.jezhumble.javasysmon; -public class MacOsXMonitor implements Monitor { +class MacOsXMonitor implements Monitor { private static Monitor monitor = null; diff --git a/src/main/java/com/jezhumble/javasysmon/NativeLibraryLoader.java b/src/main/java/com/jezhumble/javasysmon/NativeLibraryLoader.java index e6ed8e2..e25049a 100644 --- a/src/main/java/com/jezhumble/javasysmon/NativeLibraryLoader.java +++ b/src/main/java/com/jezhumble/javasysmon/NativeLibraryLoader.java @@ -3,7 +3,7 @@ import java.io.*; // This is "optimised" based on the fact we only load each native library once. -public class NativeLibraryLoader { +class NativeLibraryLoader { public void loadLibrary(String libraryName) { try { InputStream is = this.getClass().getResourceAsStream("/" + libraryName); diff --git a/src/main/java/com/jezhumble/javasysmon/NullMonitor.java b/src/main/java/com/jezhumble/javasysmon/NullMonitor.java index a6c8a02..1f906db 100644 --- a/src/main/java/com/jezhumble/javasysmon/NullMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/NullMonitor.java @@ -1,6 +1,6 @@ package com.jezhumble.javasysmon; -public class NullMonitor implements Monitor { +class NullMonitor implements Monitor { public NullMonitor() { JavaSysMon.setMonitor(this); diff --git a/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java b/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java index 520f96b..95fa84a 100644 --- a/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java @@ -2,7 +2,7 @@ import java.io.IOException; -public class SolarisMonitor implements Monitor { +class SolarisMonitor implements Monitor { private static Monitor monitor = null; private final FileUtils fileUtils; diff --git a/src/main/java/com/jezhumble/javasysmon/UnixPasswdParser.java b/src/main/java/com/jezhumble/javasysmon/UnixPasswdParser.java index 51bc749..608bd1a 100644 --- a/src/main/java/com/jezhumble/javasysmon/UnixPasswdParser.java +++ b/src/main/java/com/jezhumble/javasysmon/UnixPasswdParser.java @@ -5,7 +5,7 @@ import java.io.InputStreamReader; import java.util.HashMap; -public class UnixPasswdParser { +class UnixPasswdParser { public HashMap parse() { try { diff --git a/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java b/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java index 1e98d5b..9ca4cf6 100644 --- a/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java @@ -1,6 +1,6 @@ package com.jezhumble.javasysmon; -public class WindowsMonitor implements Monitor { +class WindowsMonitor implements Monitor { private static Monitor monitor = null; static { diff --git a/src/main/java/com/jezhumble/javasysmon/package.html b/src/main/java/com/jezhumble/javasysmon/package.html new file mode 100644 index 0000000..0d47d17 --- /dev/null +++ b/src/main/java/com/jezhumble/javasysmon/package.html @@ -0,0 +1,25 @@ + + + + +

JavaSysMon is designed to provide an OS-independent way to get live system information, +such as CPU and memory usage, and manage processes, distributed as a single jar file. +It is written in C and Java. However the native binaries are hidden away inside the jar, +so you never need to worry about them.

+ +

The main API is to be found in {@link com.jezhumble.javasysmon.JavaSysMon}, so start there.

+ +

JavaSysMon is licensed according to the terms of the NetBSD (2-line BSD) license.

+ +

Related Documentation

+ + + + + + + \ No newline at end of file