引言
最近我们负责的某行业的业务平台,出现了一个非常奇葩的问题。这个项目涉及到软件平台厂家、服务器厂家、存储厂家以及真正的用户等四方关系,而我们主要负责软件平台的研发工作。平台正常运行了2年多了,去年年底存储盘阵中出现历史巡检数据丢失或者无法使用的诡异问题,软件、服务以及存储各方对根据运行日志进行了审计,各自都说没有问题,接着,请了比较权威的第三方测评单位,召开了5次讨论会,也没有分析出真正的原因, 因为每家只能证明自身没有问题,并不能证明问题真正的原因是什么环节,所以只能几家摊钱恢复数据。
俗话说:“吃一堑长一智”。业务平台作为应用层,是最接近用户的。平台一出问题,给用户的第一印象就是这个平台太烂了,又出问题了。为了以后出现问题,软件平台可以对问题进行实时追踪和根据历史数据运行记录进行审计,便于更快速的缩小问题范围,更精确的定位问题。
一、快速入门
1.1 OSHI的简介
谈到监控,最快捷的还是使用Java本身进行对JVM和操作系统的监控,方便快捷又可靠。OSHI(Operating System and Hardware Information)是Java的免费的基于JNA的(本机)操作系统和硬件信息库。它提供了一组简单易用的API,可以用于检索和监控诸如操作系统类型、处理器信息、内存使用情况、硬盘信息、网络接口等系统和硬件相关的数据。oshi支持的主要功能包括:
- 获取操作系统信息:可以获取操作系统的名称、版本、构建信息、位数等。还可以获取操作系统的启动时间、系统负载、当前进程数等信息。
- 获取硬件信息:可以获取处理器(CPU)的信息,包括型号、频率、核心数、温度等。还可以获取内存(RAM)的信息,包括总容量、可用容量、使用率等。此外,还可以获取硬盘(磁盘)的信息,包括型号、容量、使用率等。还可以获取电池、网卡、USB设备等硬件的信息。
- 获取网络信息:可以获取网络接口(网卡)的信息,包括名称、IP地址、MAC地址、接收和发送的数据量等。
- 监控系统和硬件:可以通过OSHI提供的API实时监控和收集系统和硬件的数据,例如CPU使用率、内存使用情况、网络流量等。
总的来说,OSHI是一个强大而易于使用的Java库,可用于获取和监控操作系统和硬件信息,帮助你编写更具交互性和功能性的系统监控、硬件信息获取和性能调优的应用程序。
oshi官方参考文档:https://www.oshi.ooo/oshi-core/apidocs/
1.2 引入依赖
OSHI 不需要安装任何额外的本地库,因此接入起来很方便。只需将OSHI库添加到项目的依赖项中,并使用OSHI提供的API来获取所需的系统和硬件信息,可以根据需要选择性地获取和处理各种信息。通过配置 Maven 依赖来引入 OSHI,如下所示:
<!-- https://mvnrepository.com/artifact/com.github.oshi/oshi-core -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.4.1</version>
</dependency>
这里注意的是,不同版本的 JDK 环境,需要引用不同版本的包。由于笔者使用的JDK8,这里引入的是 oshi-core-6.4.1。
1.3 涉及的包(package)
包路径 | 说明 |
---|---|
oshi.driver.linux | 提供查询Linux信息的函数 |
oshi.driver.linux.proc | 提供用于查询Linux / proc伪文件系统中的统计信息的函数 |
oshi.driver.mac | 提供查询Mac Info的功能 |
oshi.driver.mac.disk | 提供查询Mac Disk Info的功能 |
oshi.driver.mac.net | 提供查询MAC网络信息的功能 |
oshi.driver.unix | 提供用于查询所有UNIX系统通用的信息的功能 |
oshi.driver.unix.aix | 提供有关AIX的信息的函数 |
oshi.driver.unix.aix.perfstat | 使用libperfstat API提供有关AIX的信息查询信息的功能 |
oshi.driver.unix.freebsd | 提供查询FreeBSD信息的函数 |
oshi.driver.unix.freebsd.disk | 提供查询FreeBSD磁盘信息的函数 |
oshi.driver.unix.openbsd.disk | 提供查询OpenBSD信息的函数 |
oshi.driver.unix.solaris | 提供查询Solaris信息的功能 |
oshi.driver.unix.solaris.disk | 提供查询Solaris磁盘信息的功能 |
oshi.driver.unix.solaris.kstat | 提供查询Solaris KSTAT信息的函数 |
oshi.driver.windows | 提供用于在Windows中查询信息的函数 |
oshi.driver.windows.perfmon | 提供用于在Windows性能监视器(或WMI计数器表中)中查询计数器的功能 |
oshi.driver.windows.registry | 提供用于在Windows注册表中查询数据的函数 |
oshi.driver.windows.wmi | 提供函数以在WMI类中查询属性 |
oshi.hardware | 提供跨平台实现,以检索CPU,存储器,显示,磁盘,网络接口,电源,传感器和USB设备等硬件信息 |
oshi.hardware.common | 为公共代码提供抽象类 |
oshi.hardware.platform.linux | 提供有关Linux系统上的内存,电源和处理器等硬件的信息 |
oshi.hardware.platform.mac | 提供有关Mac系统上的内存,电源和处理器等硬件的信息 |
oshi.hardware.platform.unix | 为基于UNIX的操作系统提供映射 |
oshi.hardware.platform.unix.aix | 提供关于AIX系统上的内存,电源和处理器等硬件的信息 |
oshi.hardware.platform.unix.free | 提供有关内存,电源和FreeBSD系统上的处理器等硬件的信息 |
oshi.hardware.platform.unix.open | 提供有关OpenBSD系统上的内存,电源和处理器等硬件的信息 |
oshi.hardware.platform.unix.sola | 提供有关Solaris系统上的内存,电源和处理器等硬件的信息 |
oshi.hardware.platform.windows | 提供有关Windows系统上的内存,电源和处理器等硬件的信息 |
oshi.jna.platform.linux | 为Linux提供JNA库的扩展 |
oshi.jna.platform.mac | 为MacOS提供JNA库的扩展 |
oshi.jna.platform.unix | 为UNIX提供JNA库的扩展 |
oshi.jna.platform.windows | 为Windows提供JNA库的扩展 |
oshi.software.common | 为公共代码提供抽象类 |
oshi.software.os | 提供跨平台实现来检索OS、文件系统和处理信息 |
oshi.software.os.linux | 提供有关Linux上的软件和操作系统的信息 |
oshi.software.os.mac | 提供有关MacOS上的软件和操作系统的信息 |
oshi.software.os.unix.aix | 提供有关AIX上的软件和操作系统的信息 |
oshi.software.os.unix.freebsd | 提供有关FreeBSD上的软件和操作系统的信息 |
oshi.software.os.unix.openbsd | 提供有关OpenBSD上的软件和操作系统的信息 |
oshi.software.os.unix.solaris | 提供有关Solaris上的软件和操作系统的信息 |
oshi.software.os.windows | 提供有关Windows上的软件和操作系统的信息 |
oshi.util | 提供解析、格式化和其他访问的实用程序 |
oshi.util.platform.linux | 为Linux提供实用程序 |
oshi.util.platform.mac | 提供Mac的实用程序。 |
oshi.util.platform.unix.freebsd | 为FreeBSD提供实用程序 |
oshi.util.platform.unix.openbsd | 为OpenBSD提供实用程序 |
oshi.util.platform.unix.solaris | 为Solaris提供实用程序 |
oshi.util.platform.windows | 为Windows提供实用程序 |
oshi.util.tuples | 提供封装多个对象的类,旨在从方法中作为返回类型 |
1.4 涉及的核心类
方法 | 说明 |
---|---|
getOperatingSystem() | 获取操作系统信息 |
getHardware() | 获取硬件信息 |
getCurrentPlatform() |
SystemInfo systemInfo = new SystemInfo();
二、操作系统信息:OperatingSystem
2.1 总揽
操作系统(OS)是计算机上的软件,该软件管理不同程序使用其硬件的方式,并调节用户控制计算机的方式。
方法 | 说明 |
---|---|
getBitness() | 操作系统位数 |
**getChildProcesses(int var1, int var2, OperatingSystem.ProcessSort var3) ** | 获取子进程 |
getCurrentProcess() | |
getCurrentThread() | |
getDesktopWindows(boolean visibleOnly) | 有关操作系统GUI桌面上窗口的信息 |
getFamily() | 获取操作系统名称,例如 Windows |
getManufacturer() | 获取供货商,例如 Microsoft |
getFileSystem() | 获取系统硬盘信息 |
getInternetProtocolStats() | |
getNetworkParams() | 获取网络相关参数 |
getProcess(int pId) | 通过进程id 获取一个进程信息 |
getProcessCount() | 获取进程数量 |
**getProcesses(Collection pId) ** | 获取多个进程信息 |
**getProcesses(int pId, OperatingSystem.ProcessSort var2) ** | 通过进程id获取进程信息,并设置排序方式 |
getProcessId() | 获取进程id |
getServices() | 系统服务信息 |
getSystemBootTime() | 系统启动的大致时间 |
getSystemUptime() | 操作系统结束时间 |
getThreadCount() | 获取线程数 |
getThreadId() | |
getVersionInfo() | 获取操作系统版本详细信息信息 |
getSessions() | 有关当前登录到操作系统的用户的信息 |
OperatingSystem operatingSystem = new SystemInfo().getOperatingSystem();
2.2 文件系统信息:FileSystem
OperatingSystem operatingSystem = new SystemInfo().getOperatingSystem();
FileSystem fileSystem = operatingSystem.getFileSystem();
文件系统是一种逻辑安排,通常在分层树中,其中文件被放置用于存储和检索。
类名 | 方法 | 说明 |
---|---|---|
FileSystem | ||
getMaxFileDescriptors() | 最大文件描述符 | |
getOpenFileDescriptors() | 打开文件描述符 | |
getFileStores() | 获取盘符相关信息 | |
OSFileStore | ||
getDescription | 说明 | |
getFreeInodes | ||
getFreeSpace | ||
getLabel | 标签 | |
getLogicalVolume | 文件系统的逻辑卷名 | |
getMount | 文件系统的挂载点 | |
getName | 磁盘名称 | |
getOptions | 文件系统的选项 | |
getTotalInodes | ||
getTotalSpace | 总大小 | |
getType | 盘符类型 | |
getUsableSpace | 剩余大小 | |
getUUID | ||
getVolume | 文件系统的卷名 | |
updateAttributes |
2.3 网络参数信息:NetworkParams
方法 | 说明 |
---|---|
getDnsServers() | 获取域名地址 |
getHostName() | 获取主机名 |
getDomainName() | 获取域名 |
getIpv4DefaultGateway() | 获取默认Ipv4 |
getIpv6DefaultGateway() | 获取默认Ipv6 |
OperatingSystem operatingSystem = new SystemInfo().getOperatingSystem();
NetworkParams networkParams = operatingSystem.getNetworkParams();
2.4 进程信息:OSProcess
方法 | 说明 |
---|---|
getName() | 获取进程名称 |
getPath() | 获取进程所在位置 |
getCommandLine() | 获取命令行 |
getCurrentWorkingDirectory() | 获取当前工作目录 |
getUser() | 获取用户信息 |
getUserID() | 获取用户id |
getGroup() | 获取组信息 |
getGroupID() | 获取组id |
getState() | 状态 |
getProcessID() | 获取进程id |
getParentProcessID() | 获取父进程id |
getThreadCount() | 获取线程数 |
getPriority() | 优先级 |
getVirtualSize() | 虚拟大小 |
getResidentSetSize() | 实际使用物理内存 |
getKernelTime() | 内核时间 |
getUserTime() | 用户时间 |
getUpTime() | 正常运行时间 |
getStartTime() | 开始时间 |
getBytesRead() | 读取字节 |
getBytesWritten() | 写入字节 |
getOpenFiles() | 打开文件数量 |
/**
* 获取进程信息
*/
public static Map<String, Object> getProcessesInfo() {
OperatingSystem operatingSystem = new SystemInfo().getOperatingSystem();
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
GlobalMemory globalMemory = hardware.getMemory();
Map<String, Object> processesInfoMap = new ConcurrentHashMap<>();
processesInfoMap.put("processCount", operatingSystem.getProcessCount());
processesInfoMap.put("threadCount", operatingSystem.getThreadCount());
List<OSProcess> osProcessList = operatingSystem.getProcesses(OperatingSystem.ProcessFiltering.ALL_PROCESSES, OperatingSystem.ProcessSorting.CPU_DESC, 100);
List<Map<String, Object>> osProcessMapList = new ArrayList<>(osProcessList.size());
for (int i = 0; i < osProcessList.size(); i++) {
OSProcess osProcess = osProcessList.get(i);
Map<String, Object> osProcessMap = new ConcurrentHashMap<>();
osProcessMap.put("index", i);
// 进程id
osProcessMap.put("id", osProcess.getProcessID());
// 父进程id
osProcessMap.put("pid", osProcess.getParentProcessID());
// 状态
osProcessMap.put("state", osProcess.getState().name());
// 命令行
osProcessMap.put("commandLine", osProcess.getCommandLine());
// 内核时间
osProcessMap.put("kernelTime", osProcess.getKernelTime());
// 用户时间
osProcessMap.put("userTime", osProcess.getUserTime());
// 正常运行时间
osProcessMap.put("upTime", osProcess.getUpTime());
// 开始时间
osProcessMap.put("startTime", osProcess.getStartTime());
// 读取字节
osProcessMap.put("bytesRead", osProcess.getBytesRead());
// 写入字节
osProcessMap.put("bytesWritten", osProcess.getBytesWritten());
// 打开文件数量
osProcessMap.put("openFiles", osProcess.getOpenFiles());
// 优先级
osProcessMap.put("priority", osProcess.getPriority());
// 线程数
osProcessMap.put("threadCount", osProcess.getThreadCount());
// 组信息
osProcessMap.put("group", osProcess.getGroup());
// 组id
osProcessMap.put("groupId", osProcess.getGroupID());
// 用户信息
osProcessMap.put("user", osProcess.getUser());
// 用户id
osProcessMap.put("userId", osProcess.getUserID());
// 获取当前工作目录
osProcessMap.put("currentWorkingDirectory", osProcess.getCurrentWorkingDirectory());
// 进程所在位置
osProcessMap.put("path", osProcess.getPath());
// 虚拟大小
osProcessMap.put("virtualMemSize", FormatUtil.formatBytes(osProcess.getVirtualSize()));
// 实际使用物理内存
osProcessMap.put("residentSetSize", FormatUtil.formatBytes(osProcess.getResidentSetSize()));
// 进程名称
osProcessMap.put("processName", osProcess.getName());
// 进程的命令行参数列表
osProcessMap.put("arguments", osProcess.getArguments());
// 环境变量
osProcessMap.put("environmentVariables", osProcess.getEnvironmentVariables());
// cpu 使用率
osProcessMap.put("cpuUsageRate", 100d * (osProcess.getKernelTime() + osProcess.getUserTime()) / osProcess.getUpTime());
// 内存 使用率
osProcessMap.put("memUsageRate", 100d * osProcess.getResidentSetSize() / globalMemory.getTotal());
osProcessMap.put("softOpenFileLimit", osProcess.getSoftOpenFileLimit());
osProcessMap.put("hardOpenFileLimit", osProcess.getHardOpenFileLimit());
osProcessMap.put("processCpuLoadCumulative", osProcess.getProcessCpuLoadCumulative());
osProcessMap.put("processCpuLoadBetweenTicks", osProcess.getProcessCpuLoadBetweenTicks(osProcess));
osProcessMap.put("bitness", osProcess.getBitness());
osProcessMap.put("affinityMask", osProcess.getAffinityMask());
osProcessMap.put("minorFaults", osProcess.getMinorFaults());
osProcessMap.put("majorFaults", osProcess.getMajorFaults());
osProcessMapList.add(osProcessMap);
}
processesInfoMap.put("osProcessMapList", osProcessMapList);
return processesInfoMap;
}
这里提到一个类 OSProcess.State,其是一个内部枚举类,用于表示操作系统进程的状态,定义了以下几种状态:
状态值 | 说明 |
---|---|
RUNNING | 进程正在运行中 |
BLOCKED | 进程正在等待某个资源,无法继续执行 |
WAITING | 进程正在等待某个事件发生,例如I/O操作完成 |
ZOMBIE | 进程已经结束,但其父进程尚未获取其退出状态信息 |
TERMINATED | 进程已经正常结束或异常终止 |
除了以上状态外,OSProcess.State 类还定义了一些其他状态。不过,根据不同的操作系统和Java版本,OSProcess.State类中可能还有一些其他状态。
2.5 线程信息:OSThread
在oshi库中,OSThread类表示操作系统线程。它提供了获取与操作系统线程相关的信息的方法。
方法 | 说明 |
---|---|
getContextSwitches | |
getKernelTime | |
getMajorFaults | |
getMinorFaults | |
getName | 当前线程的名称 |
getOwningProcessId | |
getPriority | 当前线程的优先级 |
getStartMemoryAddress | |
getStartTime | |
getState | 获取当前线程的状态,例如新建、可运行、阻塞等 |
getThreadCpuLoadBetweenTicks | |
getThreadCpuLoadCumulative | |
getThreadId | 当前线程的ID |
getUpTime | |
getUserTime | |
updateAttributes |
三、硬件信息:Hardware
3.1 硬件信息:HardwareAbstractionLayer
3.1.1 总揽
// 获取硬件信息
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
方法 | 说明 |
---|---|
getComputerSystem() | 获取计算机系统信息 |
getProcessor() | 获取处理器信息 |
getMemory() | 获取内存信息 |
getPowerSources() | 获取电源信息 |
getDiskStores() | 获取硬件磁盘信息 |
getNetworkIFs() | 获取网络信息 |
getDisplays() | 获取显示信息 |
getSensors() | 获取传感器信息 |
getUsbDevices(boolean var1) | 获取USB设备信息 |
3.1.2 磁盘信息:HWDiskStore
// 获取硬件信息
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<HWDiskStore> diskStores = hardware.getDiskStores();
类名 | 属性 | 类型 | 说明 |
---|---|---|---|
HWDiskStore | |||
getName() | 获取名称 | ||
getModel() | 获取型号 | ||
getSerial() | 获取序列号 | ||
getSize() | 获取大小 | ||
getReads() | 读长 | ||
getReadBytes() | 读取字节 | ||
getWrites() | 写长 | ||
getWriteBytes() | 写入字节 | ||
getTransferTime() | 获取转移时间 | ||
getPartitions() | 获取分区 | ||
getTimeStamp() | 获取时间戳 | ||
getCurrentQueueLength() | 当前队列长度 | ||
HWPartition | |||
3.1.3 内存信息:Memory
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
GlobalMemory globalMemory = hardware.getMemory();
VirtualMemory virtualMemory = globalMemory.getVirtualMemory();
List<PhysicalMemory> physicalMemoryList = globalMemory.getPhysicalMemory();
类名 | 说明 |
---|---|
GlobalMemory | 负责跟踪计算机物理内存(RAM)以及可用虚拟内存使用情况 |
VirtualMemory | 用于获取虚拟内存的相关信息 |
PhysicalMemory | 用于获取物理内存的相关信息 |
类对象 | 方法 | 类型 | 说明 |
---|---|---|---|
GlobalMemory | |||
getTotal() | long | 获取以字节为单位的实际内存数量 | |
getAvailable() | long | 获取以字节为单位的当前可用的物理内存量 | |
getSwapTotal() | long | 获取可用虚拟总内存 | |
getSwapUsed() | long | 获取已用虚拟总内存 | |
getVirtualMemory() | |||
getPhysicalMemory() | List | ||
VirtualMemory | |||
getSwapTotal() | long | 用于获取交换空间的总大小 | |
getSwapUsed() | long | 用于获取已使用的交换空间的大小 | |
getVirtualMax(); | long | 用于获取系统支持的最大虚拟内存大小 | |
getVirtualInUse() | long | 用于获取当前正在使用的虚拟内存的大小 | |
getSwapPagesIn() | long | 于获取最近从硬盘上换入的页面数 | |
getSwapPagesOut() | long | ||
PhysicalMemory | |||
getBankLabel() | String | 用于获取内存条的标签或标识符 | |
getCapacity() | long | 用于获取物理内存的容量 | |
getClockSpeed() | long | 用于获取物理内存的时钟速度 | |
getManufacturer() | String | ||
getMemoryType() | String |
3.1.4 显卡信息:graphicsCard
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<GraphicsCard> graphicsCards = hardware.getGraphicsCards()
方法 | 说明 |
---|---|
getName() | 名称 |
getDeviceId() | 设备号 |
getVendor() | 制造商 |
getVersionInfo() | 版本信息 |
3.1.5 网络接口信息:NetworkIF
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<NetworkIF> networkIFs = hardware.getNetworkIFs();
方法 | 说明 |
---|---|
getName() | 获取名称 |
getDisplayName() | 获取显示名称 |
getMTU() | 获取最大传输单元 |
getMacaddr() | 获取MAC地址 |
getIPv4addr() | 获取IPv4 |
getIPv6addr() | 获取IPv6 |
getBytesRecv() | 获取接收字节数 |
getBytesSent() | 获取发送字节数 |
getPacketsRecv() | 获取接收数据包 |
getPacketsSent() | 获取发送数据包 |
getInErrors() | 是否可达,正常 0 |
getOutErrors() | 响应错误,无错误 0 |
getSpeed() | 获取速率 |
getTimeStamp() | 获取时间戳 |
3.1.6 电源信息:PowerSource
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<PowerSource> powerSources = hardware.getPowerSources();
方法 | 说明 |
---|---|
getAmperage() | 安培 |
getCapacityUnits() | 容量单位 |
getChemistry() | |
getCurrentCapacity() | 当前容量 |
getCycleCount() | 循环次数 |
getDesignCapacity() | 初始容量 |
getDeviceName() | 设备名字 |
getManufactureDate() | 制造日期 |
getManufacturer() | 制造商 |
getMaxCapacity() | 电池当前最大容量 |
getName() | 获取名称 |
getPowerUsageRate() | 电池使用率 |
getRemainingCapacityPercent() | 电量剩余百分比 |
getSerialNumber() | |
getTemperature() | 当前温度 |
getTimeRemainingEstimated() | |
getTimeRemainingInstant() | |
getVoltage() | 电压 |
isCharging() | |
isDischarging() | |
isPowerOnLine() |
3.1.7 传感器信息:Sensors
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
Sensors sensors = hardware.getSensors();
方法 | 说明 |
---|---|
getCpuTemperature() | 获取CPU温度 |
getFanSpeeds() | 获取风扇速度 |
getCpuVoltage() | 获取CPU电压 |
3.1.8 usb设备信息:UsbDevice
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<UsbDevice> usbDevices = hardware.getUsbDevices(true);
方法 | 说明 |
---|---|
getName() | 获取名称 |
getVendor() | 获取供应商 |
getVendorId() | 获取供应商id |
getProductId() | 获取商品id |
getSerialNumber() | 获取序列号 |
getConnectedDevices() | 获取连接设备 |
3.2 CPU信息:CentralProcessor
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
CentralProcessor processor = hardware.getProcessor();
类名 | 方法 | 说明 |
---|---|---|
CentralProcessor | ||
getVendor() | 获取供应商 | |
getName() | 获取cpu名称 | |
getVendorFreq() | 获取供应商频率 | |
getProcessorID() | 获取处理器id | |
getIdentifier() | 获取标识符 | |
isCpu64bit() | 判断cpu是否为64位的 | |
getStepping() | 获取cpu步进 | |
getModel() | 获取型号 | |
getFamily() | 获取家族 | |
getSystemCpuLoadBetweenTicks() | 获取cpu负载间隔刻度 | |
getSystemCpuLoadTicks() | 获取cpu负载刻度 | |
getSystemCpuLoad() | 获取cpu负载 | |
getSystemLoadAverage() | 获取cpu平均负载 | |
getSystemLoadAverage(int var1) | 获取cpu平均负载 | |
getProcessorCpuLoadBetweenTicks() | 获取处理器cpu负载间隔刻度 | |
getProcessorCpuLoadTicks() | 获取处理器cpu负载刻度 | |
getSystemUptime() | 获取正常运行时间 | |
getLogicalProcessorCount() | 获取逻辑处理器数量 | |
getPhysicalProcessorCount() | 获取物理处理器数量 | |
getPhysicalPackageCount() | 获取物理包装数量 | |
getContextSwitches() | 获取上下文切换数量 | |
getInterrupts() | 获取中断 | |
LogicalProcessor | ||
getNumaNode | NUMA节点 | |
getPhysicalPackageNumber | 物理包数 | |
getPhysicalProcessorNumber | 物理处理器数 | |
getProcessorGroup | 处理器组 | |
getProcessorNumber | 处理器序号 | |
PhysicalProcessor | ||
getEfficiency | 效率 | |
getIdString | 字符串id | |
getPhysicalPackageNumber | 物理包数 | |
getPhysicalProcessorNumber | 物理处理器数 | |
ProcessorIdentifier | ||
getFamily | 族 | |
getIdentifier | 标识符 | |
getMicroarchitecture | 微架构 | |
getModel | 型号 | |
getName | 名称 | |
getProcessorID | 处理器编号 | |
getStepping | 步进 | |
getVendor | cpu供应商 | |
getVendorFreq | 厂家频率 | |
isCpu64bit | 是否是64位系统 |
3.3 计算机系统:ComputerSystem
计算机系统代表计算机系统/产品的物理硬件,包括BIOS /固件和主板、逻辑板等。
// 获取硬件信息
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
ComputerSystem computerSystem = hardware.getComputerSystem();
属性 | 子属性 | 类型 | 说明 |
---|---|---|---|
manufacturer | String | 制造商 | |
model | String | 型号 | |
serialNumber | String | 序列号 | |
Firware | 固件信息 | ||
name | String | 固件名称 | |
version | String | 固件版本 | |
describe | String | 固件描述 | |
manufacturer | String | 制造商 | |
releaseDate | String | 发行日期 | |
Baseboard | 主板信息 | ||
version | String | 主板版本 | |
model | String | 模型 | |
serialNumber | String | 序列号 | |
manufacturer | String | 制造商 |
四、使用场景
4.1 获取 CPU 信息
想要获取 CPU 信息,就需要CentralProcessor 类(中央处理器)作为参数,oshi库获取CentralProcessor 类步骤为:
-
首先实例化内置的SystemInfo类,该类用于访问系统和硬件信息。
-
然后根据此类的内置方法获取硬件抽象层类 HardwareAbstractionLayer 类,主要用于将硬件抽象化,允许计算机操作系统在逻辑层而不是硬件层与硬件设备交互。
-
最后根据HardwareAbstractionLayer类内置方法获取CentralProcessor 类,提供setCpuInfo方法参数
public static Map<String, Object> getCpuInfo() throws InterruptedException {
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
Map<String, Object> cpuInfo = Maps.newHashMap();
CentralProcessor processor = hardware.getProcessor();
// 第一次获取:获取系统范围的 CPU 负载滴答计数器:
long[] prevTicks = processor.getSystemCpuLoadTicks();
//等待一段时间
java.lang.Thread.sleep(1000);
//第二次获取:获取系统范围的 CPU 负载滴答计数器:
long[] ticks = processor.getSystemCpuLoadTicks();
long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
long ioWait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.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 totalCpu = user + nice + cSys + idle + ioWait + irq + softIrq + steal;
// cpu供应商
cpuInfo.put("cpuVendor", processor.getProcessorIdentifier().getVendor());
// cpu名称
cpuInfo.put("cpuName", processor.getProcessorIdentifier().getName());
// CPU核心数
cpuInfo.put("cpuNum", processor.getLogicalProcessorCount());
// CPU总的使用率
cpuInfo.put("totalPercent", totalCpu);
// CPU用户使用率,表示用户模式下花费的CPU时间
cpuInfo.put("usedPercent", new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
// CPU当前等待率,表示等待I/O操作的进程所花费的CPU时间
cpuInfo.put("waitPercent", new DecimalFormat("#.##%").format(ioWait * 1.0 / totalCpu));
// CPU系统使用率,表示系统进程所花费的CPU时间
cpuInfo.put("sysPercent", new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
// CPU当前空闲率,表示空闲进程所花费的CPU时间
cpuInfo.put("idlePercent", new DecimalFormat("#.##%").format(idle * 1.0 / totalCpu));
// 表示在nice值为0~99之间的进程所花费的CPU时间
cpuInfo.put("nicePercent", new DecimalFormat("#.##%").format(nice * 1.0 / totalCpu));
// 表示处理中断的进程所花费的CPU时间
cpuInfo.put("irqPercent", new DecimalFormat("#.##%").format(irq * 1.0 / totalCpu));
// 表示处理软中断的进程所花费的CPU时间
cpuInfo.put("softIrqPercent", new DecimalFormat("#.##%").format(softIrq * 1.0 / totalCpu));
// 表示被其他线程“偷走”的CPU时间
cpuInfo.put("stealPercent", new DecimalFormat("#.##%").format(steal * 1.0 / totalCpu));
// 物理处理器数量
cpuInfo.put("physicalProcessorCount", processor.getPhysicalProcessorCount());
return cpuInfo;
}
4.2 获取内存信息
想要获取内存信息,这就需要硬件抽象层类提供的GlobalMemory类作为参数,通过GlobalMemory类的内置方法来获取内存信息。
public static Map<String, Object> getMemoryInfo() {
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
GlobalMemory globalMemory = hardware.getMemory();
Map<String, Object> gmMap = Maps.newHashMap();
// 总内存
gmMap.put("total", FormatUtil.formatBytes(globalMemory.getTotal()));
// 剩余【当前可用的物理内存量】
gmMap.put("available", FormatUtil.formatBytes(globalMemory.getAvailable()));
// 已使用
gmMap.put("used", FormatUtil.formatBytes(globalMemory.getTotal() - globalMemory.getAvailable()));
// 空闲率
gmMap.put("freeRate", 100d * (globalMemory.getAvailable()) / globalMemory.getTotal());
// 使用率
gmMap.put("usageRate", 100d * (globalMemory.getTotal() - globalMemory.getAvailable()) / globalMemory.getTotal());
gmMap.put("pageSize", globalMemory.getPageSize());
VirtualMemory virtualMemory = globalMemory.getVirtualMemory();
Map<String, Object> vmMap = Maps.newHashMap();
vmMap.put("toString", virtualMemory);
vmMap.put("swapTotal", FormatUtil.formatBytes(virtualMemory.getSwapTotal()));
vmMap.put("swapUsed", FormatUtil.formatBytes(virtualMemory.getSwapUsed()));
vmMap.put("swapUsageRate", 100d * virtualMemory.getSwapUsed() / virtualMemory.getSwapTotal());
vmMap.put("virtualMax", FormatUtil.formatBytes(virtualMemory.getVirtualMax()));
vmMap.put("virtualInUse", FormatUtil.formatBytes(virtualMemory.getVirtualInUse()));
vmMap.put("virtualUsageRate", 100d * virtualMemory.getVirtualInUse() / virtualMemory.getVirtualMax());
gmMap.put("virtualMemory", vmMap);
List<PhysicalMemory> physicalMemoryList = globalMemory.getPhysicalMemory();
List<Map<String, Object>> pmInfoList = new ArrayList<>(physicalMemoryList.size());
for (PhysicalMemory pm : physicalMemoryList) {
Map<String, Object> pmMap = Maps.newHashMap();
pmMap.put("toString", String.valueOf(pm));
pmMap.put("bankLabel", pm.getBankLabel());
pmMap.put("manufacturer", pm.getManufacturer());
pmMap.put("capacity", FormatUtil.formatBytes(pm.getCapacity()));
pmMap.put("memoryType", pm.getMemoryType());
pmMap.put("clockSpeed", FormatUtil.formatHertz(pm.getClockSpeed()));
pmInfoList.add(pmMap);
}
gmMap.put("physicalMemoryList", pmInfoList);
return gmMap;
}
4.3 获取服务器信息
首先调用Java内置的System类的 getProperties() 方法,获取当前系统属性集,并作为一个Properties对象返回,并通过对该属性集通过传参查询,得到操作系统名称、系统架构、项目路径等信息。
public static Map<String, Object> getSysInfo() throws UnknownHostException {
Map<String, Object> sysInfo = Maps.newHashMap();
Properties props = System.getProperties();
// 操作系统
sysInfo.put("osName", props.getProperty("os.name"));
// 系统架构
sysInfo.put("osArch", props.getProperty("os.arch"));
// 服务器名称
sysInfo.put("computerName", InetAddress.getLocalHost().getHostName());
// 服务器IP
sysInfo.put("computerIp", InetAddress.getLocalHost().getHostAddress());
// 项目路径
sysInfo.put("userDir", props.getProperty("user.dir"));
// 操作系统信息
sysInfo.put("desktop", props.getProperty("sun.desktop"));
return sysInfo;
}
4.4 获取Java虚拟机信息
首先通过System系统类获取当前系统属性集后,使用Properties对象传参查询的得到JDK版本与路径;通过获得Java内置的RunTime对象(每个Java应用程序都有一个单独的Runtime类实例,它允许应用程序与运行应用程序的环境进行接口。当前运行时可以从getRuntime方法中获得)获取Java虚拟机的总内存量、 Java 虚拟机试图使用的最大内存量、Java虚拟机中的可用内存量。
public static Map<String, Object> getJvmInfo() {
Map<String, Object> jvmInfo = new ConcurrentHashMap<>();
Properties props = System.getProperties();
Runtime runtime = Runtime.getRuntime();
long jvmTotalMemoryByte = runtime.totalMemory();
long jvmFreeMemoryByte = runtime.freeMemory();
long jvmUseMemoryByte = jvmTotalMemoryByte - jvmFreeMemoryByte;
// jvm总内存
jvmInfo.put("totalMemory", FormatUtil.formatBytes(jvmTotalMemoryByte));
// JVM空闲内存
jvmInfo.put("freeMemory", FormatUtil.formatBytes(jvmFreeMemoryByte));
// Jvm已使用内存
jvmInfo.put("usedMemory", FormatUtil.formatBytes(jvmUseMemoryByte));
// JVM最大可用内存总数
jvmInfo.put("maxMemory", FormatUtil.formatBytes(runtime.maxMemory()));
// jvm内存使用率
jvmInfo.put("useRate", new DecimalFormat("#.##%").format((jvmUseMemoryByte) * 1.0 / jvmTotalMemoryByte));
// jvm内存空闲率
jvmInfo.put("freeRate", new DecimalFormat("#.##%").format((jvmFreeMemoryByte) * 1.0 / jvmTotalMemoryByte));
// Java版本
jvmInfo.put("jdkVersion", props.getProperty("java.version"));
// jdk安装目录
jvmInfo.put("jdkHome", props.getProperty("java.home"));
// java类包的路径
props.getProperty("java.class.path");
//java虚拟机制造商
props.getProperty("java.vm.vendor");
// jdk bin目录
props.getProperty("sun.boot.library.path");
// java运行环境版本
props.getProperty("java.runtime.version");
// 依赖路径
props.getProperty("java.library.path");
// java制造商
props.getProperty("java.vendor");
// java虚拟机信息
props.getProperty("java.vm.info");
// java虚拟机版本
props.getProperty("java.vm.version");
// java类版本
props.getProperty("java.class.version");
return jvmInfo;
}
4.5 获取系统文件相关信息
首先通过 SystemInfo类获取当前平台操作系统的新实例,再根据 OperatingSystem.getFileSystem()方法实例化FileSystem对象,再通过 getFileStores() 获取本机上文件存储实例化OSFileStore对象列表,表示存储池、设备、分区、卷、具体的文件系统或其他实现特定的文件存储方法信息,该方法会返回OSFileStore对象列表。最后遍历此集合获取磁盘状态信息。
public static Map<String, Object> getFileSystemInfo() {
Map<String, Object> fsInfo = new ConcurrentHashMap<>();
FileSystem fileSystem = new SystemInfo().getOperatingSystem().getFileSystem();
List<Map<String, Object>> fileSystemInfos = new ArrayList<>();
// 打开文件描述符
fsInfo.put("openFileDescriptors", fileSystem.getOpenFileDescriptors());
// 最大文件描述符
fsInfo.put("maxFileDescriptors", fileSystem.getMaxFileDescriptors());
fsInfo.put("fileDescriptors", String.format("%d/%d", fileSystem.getOpenFileDescriptors(), fileSystem.getMaxFileDescriptors()));
fsInfo.put("fdUsageRate", (100d * fileSystem.getOpenFileDescriptors() / fileSystem.getMaxFileDescriptors()) + "%");
List<OSFileStore> fileStores = fileSystem.getFileStores();
for (int i = 0; i < fileStores.size(); i++) {
Map<String, Object> fileStoreInfo = Maps.newHashMap();
fileStoreInfo.put("index", i);
OSFileStore osFileStore = fileStores.get(i);
// 磁盘名称
fileStoreInfo.put("name", osFileStore.getName());
// 文件系统的卷名
fileStoreInfo.put("volume", osFileStore.getVolume());
// 标签
fileStoreInfo.put("label", osFileStore.getLabel());
// 文件系统的逻辑卷名
fileStoreInfo.put("logicalVolume", osFileStore.getLogicalVolume());
// 文件系统的挂载点
fileStoreInfo.put("mount", osFileStore.getMount());
// 说明
fileStoreInfo.put("description", osFileStore.getDescription());
// 盘符类型
fileStoreInfo.put("sysTypeName", osFileStore.getType());
// 文件系统的选项
fileStoreInfo.put("options", osFileStore.getOptions());
fileStoreInfo.put("uuid", osFileStore.getUUID());
fileStoreInfo.put("freeSpace", osFileStore.getFreeSpace());
// 剩余大小
fileStoreInfo.put("usableSpace", FormatUtil.formatBytes(osFileStore.getUsableSpace()));
// 总大小
fileStoreInfo.put("totalSpace", FormatUtil.formatBytes(osFileStore.getTotalSpace()));
fileStoreInfo.put("freeInodes", FormatUtil.formatValue(osFileStore.getFreeInodes(), ""));
fileStoreInfo.put("totalInodes", FormatUtil.formatValue(osFileStore.getTotalInodes(), ""));
// 已经使用量
fileStoreInfo.put("usedSpace", FormatUtil.formatBytes(osFileStore.getTotalSpace() - osFileStore.getUsableSpace()));
// 使用率
String usageRate = "0";
if (osFileStore.getTotalSpace() > 0) {
usageRate = new DecimalFormat("#.##%").format((osFileStore.getTotalSpace() - osFileStore.getUsableSpace()) * 1.0 / osFileStore.getTotalSpace());
}
fileStoreInfo.put("usageRate", usageRate);
fileStoreInfo.put("inodesUsageRate", 100d * osFileStore.getFreeInodes() / osFileStore.getTotalInodes());
fileSystemInfos.add(fileStoreInfo);
}
fsInfo.put("fileStores", fileSystemInfos);
return fsInfo;
}
4.6 获取磁盘信息
public static List<Map<String, Object>> getDiskStoreInfo() {
HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
List<HWDiskStore> diskStores = hardware.getDiskStores();
List<Map<String, Object>> dsList = new ArrayList<>(diskStores.size());
for (int i = 0; i < diskStores.size(); i++) {
HWDiskStore hwDiskStore = diskStores.get(i);
Map<String, Object> hwDsMap = new ConcurrentHashMap<>();
hwDsMap.put("index", i);
// 磁盘名称
hwDsMap.put("name", hwDiskStore.getName());
hwDsMap.put("currentQueueLength", hwDiskStore.getCurrentQueueLength());
// 型号
hwDsMap.put("model", hwDiskStore.getModel());
// 序列号
hwDsMap.put("serial", hwDiskStore.getSerial());
// 大小
hwDsMap.put("size", FormatUtil.formatBytes(hwDiskStore.getSize()));
// 读长
hwDsMap.put("reads", FormatUtil.formatBytes(hwDiskStore.getReads()));
// 写长
hwDsMap.put("writes", FormatUtil.formatBytes(hwDiskStore.getWrites()));
// 读取字节
hwDsMap.put("readBytes", hwDiskStore.getReadBytes());
// 写入字节
hwDsMap.put("writeBytes", hwDiskStore.getWriteBytes());
// 转移时间
hwDsMap.put("transferTime", hwDiskStore.getTransferTime());
// 时间戳
hwDsMap.put("timeStamp", hwDiskStore.getTimeStamp());
List<HWPartition> partitions = hwDiskStore.getPartitions();
List<Map<String, Object>> partitionList = new ArrayList<>(partitions.size());
for (HWPartition partition : partitions) {
Map<String, Object> partitionMap = Maps.newHashMap();
// 分区大小
partitionMap.put("size", FormatUtil.formatBytes(partition.getSize()));
// 分区名称
partitionMap.put("name", partition.getName());
// 分区类型
partitionMap.put("type", partition.getType());
partitionMap.put("identification", partition.getIdentification());
partitionMap.put("major", partition.getMajor());
partitionMap.put("uuid", partition.getUuid());
partitionMap.put("mountPoint", partition.getMountPoint());
partitionMap.put("minor", partition.getMinor());
partitionList.add(partitionMap);
}
hwDsMap.put("partitionList", partitionList);
dsList.add(hwDsMap);
}
return dsList;
}
小结
把今天最好的表现当作明天最新的起点..~
投身于天地这熔炉,一个人可以被毁灭,但绝不会被打败!一旦决定了心中所想,便绝无动摇。迈向光明之路,注定荆棘丛生,自己选择的路,即使再荒谬、再艰难,跪着也要走下去!放弃,曾令人想要逃离,但绝境重生方为宿命。若结果并非所愿,那就在尘埃落定前奋力一搏!