RealMetricsProvider.java
package com.guinetik.hexafun.examples.sysmon;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
/**
* Real implementation of MetricsProvider using JVM/OS metrics.
*
* <p>Uses Java's management beans to read actual system metrics.
* Note: CPU load may return -1 if not available on the platform.</p>
*/
public class RealMetricsProvider implements MetricsProvider {
private final OperatingSystemMXBean osBean;
private final MemoryMXBean memoryBean;
public RealMetricsProvider() {
this.osBean = ManagementFactory.getOperatingSystemMXBean();
this.memoryBean = ManagementFactory.getMemoryMXBean();
}
@Override
public double getCpuUsage() {
if (
osBean instanceof com.sun.management.OperatingSystemMXBean sunBean
) {
double load = sunBean.getCpuLoad();
// First call returns -1, need to wait and retry
if (load < 0) {
try {
Thread.sleep(100); // Let it collect data
load = sunBean.getCpuLoad();
} catch (InterruptedException ignored) {}
}
if (load >= 0) {
return load * 100.0;
}
}
return -1;
}
@Override
public double getMemoryUsage() {
if (
osBean instanceof com.sun.management.OperatingSystemMXBean sunBean
) {
long total = sunBean.getTotalMemorySize();
long free = sunBean.getFreeMemorySize();
if (total > 0) {
return ((double) (total - free) / total) * 100.0;
}
}
// Fallback: JVM heap usage (not system memory, but better than nothing)
var heap = memoryBean.getHeapMemoryUsage();
return ((double) heap.getUsed() / heap.getMax()) * 100.0;
}
@Override
public double getDiskUsage() {
// Get all roots and pick the main one
File[] roots = File.listRoots();
if (roots.length == 0) return -1;
// Use first root (C:\ on Windows, / on Unix)
File root = roots[0];
long total = root.getTotalSpace();
long free = root.getUsableSpace(); // usableSpace is more accurate than freeSpace
if (total > 0) {
return ((double) (total - free) / total) * 100.0;
}
return -1;
}
}