This repository has been archived on 2023-10-27. You can view files and clone it, but cannot push or open issues or pull requests.
McGamerZone/commons/src/main/java/zone/themcgamer/common/CpuMonitor.java
2021-02-19 15:11:08 -05:00

158 lines
6.1 KiB
Java

package zone.themcgamer.common;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author Lucko
* credits = https://github.com/lucko/spark
*/
public enum CpuMonitor {
;
/** The object name of the com.sun.management.OperatingSystemMXBean */
private static final String OPERATING_SYSTEM_BEAN = "java.lang:type=OperatingSystem";
/** The OperatingSystemMXBean instance */
private static final OperatingSystemMXBean BEAN;
/** The executor used to monitor & calculate rolling averages. */
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor(r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setName("core-cpu-monitor");
thread.setDaemon(true);
return thread;
});
// Rolling averages for system/process data
private static final RollingAverage SYSTEM_AVERAGE_10_SEC = new RollingAverage(10);
private static final RollingAverage SYSTEM_AVERAGE_1_MIN = new RollingAverage(60);
private static final RollingAverage SYSTEM_AVERAGE_15_MIN = new RollingAverage(60 * 15);
private static final RollingAverage PROCESS_AVERAGE_10_SEC = new RollingAverage(10);
private static final RollingAverage PROCESS_AVERAGE_1_MIN = new RollingAverage(60);
private static final RollingAverage PROCESS_AVERAGE_15_MIN = new RollingAverage(60 * 15);
static {
try {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName diagnosticBeanName = ObjectName.getInstance(OPERATING_SYSTEM_BEAN);
BEAN = JMX.newMXBeanProxy(beanServer, diagnosticBeanName, OperatingSystemMXBean.class);
} catch (Exception e) {
throw new UnsupportedOperationException("OperatingSystemMXBean is not supported by the system", e);
}
// schedule rolling average calculations.
EXECUTOR.scheduleAtFixedRate(new RollingAverageCollectionTask(), 1, 1, TimeUnit.SECONDS);
}
/**
* Ensures that the static initializer has been called.
*/
@SuppressWarnings("EmptyMethod")
public static void ensureMonitoring() {
// intentionally empty
}
/**
* Returns the "recent cpu usage" for the whole system. This value is a
* double in the [0.0,1.0] interval. A value of 0.0 means that all CPUs
* were idle during the recent period of time observed, while a value
* of 1.0 means that all CPUs were actively running 100% of the time
* during the recent period being observed. All values betweens 0.0 and
* 1.0 are possible depending of the activities going on in the system.
* If the system recent cpu usage is not available, the method returns a
* negative value.
*
* @return the "recent cpu usage" for the whole system; a negative
* value if not available.
*/
public static double systemLoad() {
return BEAN.getSystemCpuLoad();
}
public static double systemLoad10SecAvg() {
return SYSTEM_AVERAGE_10_SEC.getAverage();
}
public static double systemLoad1MinAvg() {
return SYSTEM_AVERAGE_1_MIN.getAverage();
}
public static double systemLoad15MinAvg() {
return SYSTEM_AVERAGE_15_MIN.getAverage();
}
/**
* Returns the "recent cpu usage" for the Java Virtual Machine process.
* This value is a double in the [0.0,1.0] interval. A value of 0.0 means
* that none of the CPUs were running threads from the JVM process during
* the recent period of time observed, while a value of 1.0 means that all
* CPUs were actively running threads from the JVM 100% of the time
* during the recent period being observed. Threads from the JVM include
* the application threads as well as the JVM internal threads. All values
* betweens 0.0 and 1.0 are possible depending of the activities going on
* in the JVM process and the whole system. If the Java Virtual Machine
* recent CPU usage is not available, the method returns a negative value.
*
* @return the "recent cpu usage" for the Java Virtual Machine process;
* a negative value if not available.
*/
public static double processLoad() {
return BEAN.getProcessCpuLoad();
}
public static double processLoad10SecAvg() {
return PROCESS_AVERAGE_10_SEC.getAverage();
}
public static double processLoad1MinAvg() {
return PROCESS_AVERAGE_1_MIN.getAverage();
}
public static double processLoad15MinAvg() {
return PROCESS_AVERAGE_15_MIN.getAverage();
}
/**
* Task to poll CPU loads and add to the rolling averages in the enclosing class.
*/
private static final class RollingAverageCollectionTask implements Runnable {
private final RollingAverage[] systemAverages = new RollingAverage[]{
SYSTEM_AVERAGE_10_SEC,
SYSTEM_AVERAGE_1_MIN,
SYSTEM_AVERAGE_15_MIN
};
private final RollingAverage[] processAverages = new RollingAverage[]{
PROCESS_AVERAGE_10_SEC,
PROCESS_AVERAGE_1_MIN,
PROCESS_AVERAGE_15_MIN
};
@Override
public void run() {
BigDecimal systemCpuLoad = new BigDecimal(systemLoad());
BigDecimal processCpuLoad = new BigDecimal(processLoad());
if (systemCpuLoad.signum() != -1) { // if value is not negative
for (RollingAverage average : this.systemAverages) {
average.add(systemCpuLoad);
}
}
if (processCpuLoad.signum() != -1) { // if value is not negative
for (RollingAverage average : this.processAverages) {
average.add(processCpuLoad);
}
}
}
}
public interface OperatingSystemMXBean {
double getSystemCpuLoad();
double getProcessCpuLoad();
}
}