This commit is contained in:
Looly 2021-09-01 01:00:10 +08:00
parent 0343af6650
commit f9df586d09
4 changed files with 142 additions and 57 deletions

View File

@ -16,6 +16,10 @@
<name>${project.artifactId}</name>
<description>Hutool 系统调用Runtime、系统监控封装</description>
<properties>
<slf4j.version>1.7.32</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
@ -29,5 +33,11 @@
<version>5.8.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -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 + '\'' +
'}';
}
}
/**
* 获取指定等待时间内系统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)));
}
}

View File

@ -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库封装的工具类通过此工具类可获取系统硬件相关信息
*
*
* <pre>
* 1系统信息
* 2硬件信息
* </pre>
*
* <p>
* 相关内容见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<NetworkIF> getNetworkIFs(){
public static List<NetworkIF> getNetworkIFs() {
return hardware.getNetworkIFs();
}
// ------------------------------------------------------------------ cpu
/**
* 获取系统CPU 系统使用率用户使用率利用率等等 相关信息
* 获取系统CPU 系统使用率用户使用率利用率等等 相关信息<br>
* 默认间隔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);
}
}

View File

@ -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());
}
}