diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 7674a417e..2d18d2fad 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -16,6 +16,10 @@ ${project.artifactId} Hutool 系统调用(Runtime)、系统监控封装 + + 1.7.32 + + cn.hutool @@ -29,5 +33,11 @@ 5.8.1 provided + + org.slf4j + slf4j-simple + ${slf4j.version} + test + diff --git a/hutool-system/src/main/java/cn/hutool/system/oshi/CpuInfo.java b/hutool-system/src/main/java/cn/hutool/system/oshi/CpuInfo.java index faa312e06..6c36c171a 100644 --- a/hutool-system/src/main/java/cn/hutool/system/oshi/CpuInfo.java +++ b/hutool-system/src/main/java/cn/hutool/system/oshi/CpuInfo.java @@ -1,5 +1,8 @@ package cn.hutool.system.oshi; +import oshi.hardware.CentralProcessor; +import oshi.util.Util; + import java.text.DecimalFormat; /** @@ -9,6 +12,8 @@ import java.text.DecimalFormat; **/ public class CpuInfo { + private static final DecimalFormat LOAD_FORMAT = new DecimalFormat("#.00"); + /** * cpu核心数 */ @@ -47,6 +52,27 @@ public class CpuInfo { public CpuInfo() { } + /** + * 构造 + * + * @param processor {@link CentralProcessor} + * @param waitingTime 设置等待时间,单位毫秒 + */ + public CpuInfo(CentralProcessor processor, long waitingTime) { + init(processor, waitingTime); + } + + /** + * 构造 + * + * @param cpuNum CPU核心数 + * @param toTal CPU总的使用率 + * @param sys CPU系统使用率 + * @param used CPU用户使用率 + * @param wait CPU当前等待率 + * @param free CPU当前空闲率 + * @param cpuModel CPU型号信息 + */ public CpuInfo(Integer cpuNum, double toTal, double sys, double used, double wait, double free, String cpuModel) { this.cpuNum = cpuNum; this.toTal = toTal; @@ -127,4 +153,66 @@ public class CpuInfo { ", CPU型号信息='" + cpuModel + '\'' + '}'; } -} \ No newline at end of file + + /** + * 获取指定等待时间内系统CPU 系统使用率、用户使用率、利用率等等 相关信息 + * + * @param processor {@link CentralProcessor} + * @param waitingTime 设置等待时间,单位毫秒 + * @since 5.7.12 + */ + private void init(CentralProcessor processor, long waitingTime) { + // CPU信息 + final long[] prevTicks = processor.getSystemCpuLoadTicks(); + // 这里必须要设置延迟 + Util.sleep(waitingTime); + final long[] ticks = processor.getSystemCpuLoadTicks(); + final long nice = tick(prevTicks, ticks, CentralProcessor.TickType.NICE); + final long irq = tick(prevTicks, ticks, CentralProcessor.TickType.IRQ); + final long softIrq = tick(prevTicks, ticks, CentralProcessor.TickType.SOFTIRQ); + final long steal = tick(prevTicks, ticks, CentralProcessor.TickType.STEAL); + final long cSys = tick(prevTicks, ticks, CentralProcessor.TickType.SYSTEM); + final long user = tick(prevTicks, ticks, CentralProcessor.TickType.USER); + final long ioWait = tick(prevTicks, ticks, CentralProcessor.TickType.IOWAIT); + // CPU闲置时间 + final long idle = tick(prevTicks, ticks, CentralProcessor.TickType.IDLE); + + this.cpuNum = processor.getLogicalProcessorCount(); + final long totalCpu = Math.max(user + nice + cSys + idle + ioWait + irq + softIrq + steal, 0); + this.toTal = totalCpu; + + this.sys = formatDouble(cSys, totalCpu); + this.used = formatDouble(user, totalCpu); + this.wait = formatDouble(ioWait, totalCpu); + this.free = formatDouble(idle, totalCpu); + this.cpuModel = processor.toString(); + } + + /** + * 获取一段时间内的CPU负载标记差 + * + * @param prevTicks 开始的ticks + * @param ticks 结束的ticks + * @param tickType tick类型 + * @return 标记差 + * @since 5.7.12 + */ + private static long tick(long[] prevTicks, long[] ticks, CentralProcessor.TickType tickType) { + return ticks[tickType.getIndex()] - prevTicks[tickType.getIndex()]; + } + + /** + * 获取每个CPU核心的tick,计算方式为 100 * tick / totalCpu + * + * @param tick tick + * @param totalCpu CPU总数 + * @return 平均每个CPU核心的tick + * @since 5.7.12 + */ + private static double formatDouble(long tick, long totalCpu) { + if (0 == totalCpu) { + return 0D; + } + return Double.parseDouble(LOAD_FORMAT.format(tick <= 0 ? 0 : (100d * tick / totalCpu))); + } +} diff --git a/hutool-system/src/main/java/cn/hutool/system/oshi/OshiUtil.java b/hutool-system/src/main/java/cn/hutool/system/oshi/OshiUtil.java index c483c9ac8..3da3a517f 100644 --- a/hutool-system/src/main/java/cn/hutool/system/oshi/OshiUtil.java +++ b/hutool-system/src/main/java/cn/hutool/system/oshi/OshiUtil.java @@ -8,31 +8,34 @@ import oshi.hardware.HWDiskStore; import oshi.hardware.HardwareAbstractionLayer; import oshi.hardware.NetworkIF; import oshi.hardware.Sensors; +import oshi.software.os.OSProcess; import oshi.software.os.OperatingSystem; -import oshi.util.Util; -import java.text.DecimalFormat; import java.util.List; /** * Oshi库封装的工具类,通过此工具类,可获取系统、硬件相关信息 - * + * *
  * 1、系统信息
  * 2、硬件信息
  * 
- * + *

* 相关内容见:https://github.com/oshi/oshi - * + * * @author Looly * @since 4.6.4 */ public class OshiUtil { private static final SystemInfo systemInfo; - /** 硬件信息 */ + /** + * 硬件信息 + */ private static final HardwareAbstractionLayer hardware; - /** 系统信息 */ + /** + * 系统信息 + */ private static final OperatingSystem os; static { @@ -43,16 +46,26 @@ public class OshiUtil { /** * 获取操作系统相关信息,包括系统版本、文件系统、进程等 - * + * * @return 操作系统相关信息 */ public static OperatingSystem getOs() { return os; } + /** + * 获取当前进程信息{@link OSProcess} + * + * @return 进程信息 {@link OSProcess} + * @since 5.7.12 + */ + public static OSProcess getCurrentProcess() { + return os.getProcess(os.getProcessId()); + } + /** * 获取硬件相关信息,包括内存、硬盘、网络设备、显示器、USB、声卡等 - * + * * @return 硬件相关信息 */ public static HardwareAbstractionLayer getHardware() { @@ -61,7 +74,7 @@ public class OshiUtil { /** * 获取BIOS中计算机相关信息,比如序列号、固件版本等 - * + * * @return 获取BIOS中计算机相关信息 */ public static ComputerSystem getSystem() { @@ -70,7 +83,7 @@ public class OshiUtil { /** * 获取内存相关信息,比如总内存、可用内存等 - * + * * @return 内存相关信息 */ public static GlobalMemory getMemory() { @@ -79,7 +92,7 @@ public class OshiUtil { /** * 获取CPU(处理器)相关信息,比如CPU负载等 - * + * * @return CPU(处理器)相关信息 */ public static CentralProcessor getProcessor() { @@ -88,7 +101,7 @@ public class OshiUtil { /** * 获取传感器相关信息,例如CPU温度、风扇转速等,传感器可能有多个 - * + * * @return 传感器相关信息 */ public static Sensors getSensors() { @@ -97,7 +110,7 @@ public class OshiUtil { /** * 获取磁盘相关信息,可能有多个磁盘(包括可移动磁盘等) - * + * * @return 磁盘相关信息 * @since 5.3.6 */ @@ -107,17 +120,19 @@ public class OshiUtil { /** * 获取网络相关信息,可能多块网卡 + * * @return 网络相关信息 * @since 5.3.6 */ - public static List getNetworkIFs(){ + public static List getNetworkIFs() { return hardware.getNetworkIFs(); } // ------------------------------------------------------------------ cpu /** - * 获取系统CPU 系统使用率、用户使用率、利用率等等 相关信息 + * 获取系统CPU 系统使用率、用户使用率、利用率等等 相关信息
+ * 默认间隔1秒 * * @return 系统 CPU 使用率 等信息 */ @@ -128,48 +143,10 @@ public class OshiUtil { /** * 获取系统CPU 系统使用率、用户使用率、利用率等等 相关信息 * - * @param waitingTime 设置等待时间 + * @param waitingTime 设置等待时间,单位毫秒 * @return 系统 CPU 使用率 等信息 */ public static CpuInfo getCpuInfo(long waitingTime) { - return getCpuInfo(OshiUtil.getProcessor(), waitingTime); - } - - /** - * 获取系统CPU 系统使用率、用户使用率、利用率等等 相关信息 - * - * @param processor {@link CentralProcessor} - * @param waitingTime 设置等待时间 - * @return 系统 CPU 使用率 等信息 - */ - private static CpuInfo getCpuInfo(CentralProcessor processor, long waitingTime) { - CpuInfo cpuInfo = new CpuInfo(); - // CPU信息 - long[] prevTicks = processor.getSystemCpuLoadTicks(); - // 这里必须要设置延迟 - Util.sleep(waitingTime); - long[] ticks = processor.getSystemCpuLoadTicks(); - long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; - long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; - long softIrq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; - long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; - long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; - long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; - long ioWait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; - long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; - long totalCpu = Math.max(user + nice + cSys + idle + ioWait + irq + softIrq + steal, 0); - final DecimalFormat format = new DecimalFormat("#.00"); - cpuInfo.setCpuNum(processor.getLogicalProcessorCount()); - cpuInfo.setToTal(totalCpu); - cpuInfo.setSys(Double.parseDouble(format.format(cSys <= 0 ? 0 : (100d * cSys / totalCpu)))); - cpuInfo.setUsed(Double.parseDouble(format.format(user <= 0 ? 0 : (100d * user / totalCpu)))); - if (totalCpu == 0) { - cpuInfo.setWait(0); - } else { - cpuInfo.setWait(Double.parseDouble(format.format(100d * ioWait / totalCpu))); - } - cpuInfo.setFree(Double.parseDouble(format.format(idle <= 0 ? 0 : (100d * idle / totalCpu)))); - cpuInfo.setCpuModel(processor.toString()); - return cpuInfo; + return new CpuInfo(OshiUtil.getProcessor(), waitingTime); } } diff --git a/hutool-system/src/test/java/cn/hutool/system/OshiTest.java b/hutool-system/src/test/java/cn/hutool/system/OshiTest.java index abe378729..88abfdced 100644 --- a/hutool-system/src/test/java/cn/hutool/system/OshiTest.java +++ b/hutool-system/src/test/java/cn/hutool/system/OshiTest.java @@ -4,7 +4,11 @@ import cn.hutool.system.oshi.CpuInfo; import cn.hutool.system.oshi.OshiUtil; import org.junit.Assert; import org.junit.Test; +import oshi.software.os.OSProcess; +/** + * 测试参考:https://github.com/oshi/oshi/blob/master/oshi-core/src/test/java/oshi/SystemInfoTest.java + */ public class OshiTest { @Test @@ -18,4 +22,10 @@ public class OshiTest { CpuInfo cpuInfo = OshiUtil.getCpuInfo(); Assert.assertNotNull(cpuInfo); } + + @Test + public void getCurrentProcessTest() { + final OSProcess currentProcess = OshiUtil.getCurrentProcess(); + Assert.assertEquals("java", currentProcess.getName()); + } }