package org.radargun.sysmonitor; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.util.concurrent.TimeUnit; import org.radargun.reporting.Timeline; import org.radargun.traits.JmxConnectionProvider; /** * @author Galder Zamarreno */ public class CpuUsageMonitor extends JmxMonitor { private static final String CPU_USAGE = "CPU usage"; private static final String PROCESS_CPU_TIME_ATTR = "ProcessCpuTime"; long prevCpuTime; long prevUpTime; static { PERCENT_FORMATTER.setMinimumFractionDigits(1); PERCENT_FORMATTER.setMaximumIntegerDigits(3); } public CpuUsageMonitor(JmxConnectionProvider jmxConnectionProvider, Timeline timeline) { super(jmxConnectionProvider, timeline); } public synchronized void run() { try { if (connection == null) { log.warn("MBean connection is not open, cannot read CPU stats"); return; } long cpuTimeMultiplier = getCpuMultiplier(connection); OperatingSystemMXBean os = ManagementFactory.newPlatformMXBeanProxy(connection, ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class); int procCount = os.getAvailableProcessors(); long jmxCpuTime = (Long) connection.getAttribute(OS_NAME, PROCESS_CPU_TIME_ATTR); long cpuTime = jmxCpuTime * cpuTimeMultiplier; long upTime = (Long) connection.getAttribute(RUNTIME_NAME, PROCESS_UP_TIME); long upTimeDiff = TimeUnit.MILLISECONDS.toNanos(upTime - prevUpTime); long procTimeDiff = (cpuTime - prevCpuTime) / procCount; // already in nanoseconds double cpuUsage = Math.min(1d, Math.max(0d, (double) procTimeDiff / (double) upTimeDiff)); timeline.addValue(Timeline.Category.sysCategory(CPU_USAGE), new Timeline.Value(cpuUsage)); log.tracef("Current CPU usage: %.1f%%", 100 * cpuUsage); prevCpuTime = cpuTime; prevUpTime = upTime; } catch (Exception e) { log.error("Exception!", e); } } @Override public synchronized void start() { super.start(); timeline.addValue(Timeline.Category.sysCategory(CPU_USAGE), new Timeline.Value(0)); } @Override public synchronized void stop() { super.stop(); timeline.addValue(Timeline.Category.sysCategory(CPU_USAGE), new Timeline.Value(0)); } }