官方参考文档
oshi官方参考文档
依赖,本文已6.1.6版本为例
com.github.oshi oshi-core 6.1.6
package cn.piesat.demo.model.osinfo;import lombok.Data;/*** 系统信息**/
@Data
public class OSInfo {/*** 系统*/private String os;/*** 系统架构*/private String osArch;/*** java版本*/private String javaVersion;/*** 工作目录*/private String userDir;/*** cpu核心数*/private int cpuCount;/*** 主机host*/private String host;/*** 主机名称*/private String hostName;/*** 系统启动时间*/private String bootTime;
}
package cn.piesat.demo.model.osinfo;import lombok.Data;import java.util.List;/*** 系统运行时信息**/
@Data
public class OSRuntimeInfo {/*** 时刻*/private String timestamp;/*** cpu使用率*/private double cpuUsage;/*** cpu基准速度(GHz)*/private String cpuMaxFreq;/*** cpu当前速度(GHz)*/private String cpuCurrentFreq;/*** 总内存*/private long totalMemory;/*** 使用内存*/private long usedMemory;/*** 可用虚拟总内存*/private long swapTotalMemory;/*** 已用虚拟内存*/private long swapUsedMemory;/*** 磁盘信息*/private List disksList;/*** 磁盘读取速率(Kb/s)*/private Double diskReadRate;/*** 磁盘写入速率(Kb/s)*/private Double diskWriteRate;/*** 网卡信息*/private List networkList;}
package cn.piesat.demo.model.osinfo;import lombok.Data;/*** 磁盘信息封装类**/
@Data
public class DisksInfo {/*** 文件系统的挂载点*/private String dirName;/*** 文件系统名称*/private String sysTypeName;/*** 文件系统的类型(FAT,NTFS,etx2,ext4等)*/private String typeName;/*** 总大小*/private long total;/*** 剩余大小*/private long free;/*** 已经使用量*/private long used;/*** 资源的使用率*/private double usage = 100;
}
package cn.piesat.demo.model.osinfo;import lombok.Data;/*** 网卡信息包装类**/
@Data
public class NetworkInfo {/*** ipv4地址*/private String ipv4Address;/*** ipv6地址*/private String ipv6Address;/*** mac地址*/private String macAddress;/*** 网卡名称*/private String networkName;/*** 发送数据量*/private long send;/*** 接受数据量*/private long accept;/*** 网卡时间戳*/private long timeStamp;}
系统信息获取工具类SystemInfoUtil,可获取操作系统信息,系统cpu使用信息,系统内存信息(含swap内存),系统网卡信息,磁盘使用量信息。
监控结果示例:隐私信息使用xxx代替
-----------系统信息-----------
操作系统:Linux
系统架构:amd64
Java版本:1.8.0_131
工作目录:/root/server/server_monitor
cpu核心数:144
主机host:xxx
主机名称:xxx
系统正常运行时长:118天4小时25分22秒714毫秒
-----------运行时信息-----------
------cpu信息------
cpu使用率:4%
cpu基准速度:2.99 GHz
cpu速度:2.67 GHz
------内存信息------
系统内存总量:540748742656 -> 503.61 GB
系统内存使用量:223715401728 -> 208.35 GB
系统内存使用率:41.37%
可用虚拟总内存(swap):17179865088 -> 16 GB
虚拟内存使用量(swap):2711552000 -> 2.53 GB
------磁盘信息------
挂载点:/xx
文件系统名称:xxx:/xxx/xx/x
文件系统类型:nfs
磁盘总量:1928543395119104 -> 1.71 PB
磁盘使用量:1722780569567232 -> 1.53 PB
磁盘剩余量:205762825551872 -> 187.14 TB
磁盘使用率:89%
//...省略其他磁盘信息
------网卡网络信息------
ipv4地址:xxx
mac地址:xxx
网卡名称:team1
上传速度↑:15912.1Kbps
下载速度↓:1217154.3Kbps
//...省略其他网络信息
SystemInfoUtil.java 完整代码如下:
package cn.piesat.demo.util;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.oshi.OshiUtil;
import cn.piesat.demo.model.osinfo.DisksInfo;
import cn.piesat.demo.model.osinfo.NetworkInfo;
import cn.piesat.demo.model.osinfo.OSInfo;
import cn.piesat.demo.model.osinfo.OSRuntimeInfo;
import lombok.extern.slf4j.Slf4j;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;/*** 系统信息获取工具类* 1.操作系统信息* 2.系统cpu使用信息* 3.系统内存信息* 4.系统卡流量信息* 5.磁盘使用量信息*/
@Slf4j
public class SystemInfoUtil {private static SystemInfo systemInfo;private static HardwareAbstractionLayer abstractionLayer;private static OperatingSystem operatingSystem;private static CentralProcessor centralProcessor;private static GlobalMemory globalMemory;private static long[] oldTicks;private static Map networkInfoMap;private static List networkIFList;private static DecimalFormat df = new DecimalFormat("0.00");private SystemInfoUtil() {}static {try {systemInfo = new SystemInfo();abstractionLayer = systemInfo.getHardware();operatingSystem = systemInfo.getOperatingSystem();centralProcessor = abstractionLayer.getProcessor();globalMemory = abstractionLayer.getMemory();oldTicks = new long[CentralProcessor.TickType.values().length];networkInfoMap = new ConcurrentHashMap<>();networkIFList = getNetwork();} catch (Exception e) {e.printStackTrace();}}enum NetworkType {/*** 当前网卡时间戳*/TIME_STAMP(0),/*** 网卡总发送量*/SEND(1),/*** 网卡总接收量*/ACCEPT(2);private int index;NetworkType(int value) {this.index = value;}public int getIndex() {return index;}}/*** 获取磁盘列表信息** @return*/public static List getDisksList() {FileSystem fileSystem = operatingSystem.getFileSystem();List fileStores = fileSystem.getFileStores();List list = new ArrayList<>();for (int i = 0; i < fileStores.size(); i++) {OSFileStore osFileStore = fileStores.get(i);DisksInfo disksInfo = new DisksInfo();disksInfo.setDirName(osFileStore.getMount());String name = osFileStore.getName();disksInfo.setSysTypeName(name);disksInfo.setTypeName(osFileStore.getType());long total = osFileStore.getTotalSpace();long free = osFileStore.getUsableSpace();long used = total - free;if (used < 0) {// 有的挂载盘获取到的 free比total还大 不知是否是方法问题continue;}disksInfo.setTotal(total);disksInfo.setFree(free);disksInfo.setUsed(used);if (total != 0) {disksInfo.setUsage(Double.parseDouble(df.format((double) used / total)));}list.add(disksInfo);}return list;}/*** 获取网络接口NetworkIF对象列表** @return*/private static List getNetwork() {List list = new ArrayList<>();List networkIFs = abstractionLayer.getNetworkIFs();for (int i = 0; i < networkIFs.size(); i++) {NetworkIF networkIF = networkIFs.get(i);if (!networkIF.isKnownVmMacAddr()) {if (networkIF.getMacaddr() != null && networkIF.getIPv4addr().length > 0&& networkIF.getIPv6addr().length > 0) {if (!networkInfoMap.containsKey(networkIF.getMacaddr())) {networkIF.updateAttributes();Long[] data = new Long[]{networkIF.getTimeStamp(), networkIF.getBytesSent(), networkIF.getBytesRecv()};networkInfoMap.put(networkIF.getMacaddr(), data);}list.add(networkIF);}}}return list;}/*** 网卡实际的传输速率受多方面影响,具体如下:* 1、硬盘的读写(I/O)速度达不到。* 2、网卡本身性能差。* 3、交换机/(HUB)性能差。* 4、通讯线路条件质量差。* 5、网络性能差。* * 一般情况下:* 网络条件比较好的网络利用率100Mbits的一般为:1/8(此方法默认)* 网络及各方面条件差的利用率一般为:1/12*/public static List getNetworkInfo() {networkIFList = getNetwork();List list = new ArrayList<>();for (int i = 0; i < networkIFList.size(); i++) {NetworkIF networkIF = networkIFList.get(i);if (networkIF.updateAttributes()) {if (networkIF.getIPv4addr().length > 0 && networkIF.getIPv6addr().length > 0) {NetworkInfo networkInfo = new NetworkInfo();networkInfo.setIpv4Address(networkIF.getIPv4addr()[0]);networkInfo.setIpv6Address(networkIF.getIPv6addr()[0]);networkInfo.setMacAddress(networkIF.getMacaddr());networkInfo.setNetworkName(networkIF.getName());//计算Long[] oldData = networkInfoMap.get(networkIF.getMacaddr());long time = oldData[NetworkType.TIME_STAMP.getIndex()] - networkIF.getTimeStamp();if (time == 0) {continue;}long send = (oldData[NetworkType.SEND.getIndex()] - networkIF.getBytesSent()) * 8 / time * 1000;long accept = (oldData[NetworkType.ACCEPT.getIndex()] - networkIF.getBytesRecv()) * 8 / time * 1000;Long[] newData = new Long[]{networkIF.getTimeStamp(), networkIF.getBytesSent(), networkIF.getBytesRecv()};networkInfoMap.put(networkInfo.getMacAddress(), newData);//对象赋值networkInfo.setTimeStamp(networkIF.getTimeStamp());networkInfo.setSend(send);networkInfo.setAccept(accept);list.add(networkInfo);}}}return list;}/*** 获取系统运行信息** @return* @throws InterruptedException*/public static OSRuntimeInfo getOSRuntimeInfo() throws InterruptedException {OSRuntimeInfo osRuntimeInfo = new OSRuntimeInfo();osRuntimeInfo.setTimestamp(DateUtil.now());//cpu使用率osRuntimeInfo.setCpuUsage(getCpuRate());//cpu基准速度(GHz)osRuntimeInfo.setCpuMaxFreq(df.format(centralProcessor.getMaxFreq() / 1000000000.0) + " GHz");//cpu当前速度(GHz)long[] currentFreq = centralProcessor.getCurrentFreq();long avg = Arrays.stream(currentFreq).sum() / currentFreq.length;osRuntimeInfo.setCpuCurrentFreq(df.format(avg / 1000000000.0) + " GHz");//系统内存总量osRuntimeInfo.setTotalMemory(globalMemory.getTotal());//系统使用量osRuntimeInfo.setUsedMemory(globalMemory.getTotal() - globalMemory.getAvailable());//可用虚拟总内存osRuntimeInfo.setSwapTotalMemory(globalMemory.getVirtualMemory().getSwapTotal());//已用虚拟内存osRuntimeInfo.setSwapUsedMemory(globalMemory.getVirtualMemory().getSwapUsed());//磁盘信息osRuntimeInfo.setDisksList(getDisksList());//磁盘读取速率Map diskIo = getDiskIo();double diskReadRate = diskIo.get("diskReadRate");osRuntimeInfo.setDiskReadRate(diskReadRate);//磁盘写入速率double diskWriteRate = diskIo.get("diskWriteRate");osRuntimeInfo.setDiskWriteRate(diskWriteRate);//网卡信息osRuntimeInfo.setNetworkList(getNetworkInfo());return osRuntimeInfo;}public static OSInfo getSystemInfo() {Properties props = System.getProperties();OSInfo osInfo = new OSInfo();//操作系统osInfo.setOs(props.getProperty("os.name"));//系统架构osInfo.setOsArch(props.getProperty("os.arch"));//java版本osInfo.setJavaVersion(props.getProperty("java.version"));//工作目录osInfo.setUserDir(props.getProperty("user.dir"));//CPU核数osInfo.setCpuCount(centralProcessor.getLogicalProcessorCount());//主机信息try {InetAddress address = InetAddress.getLocalHost();osInfo.setHost(address.getHostAddress());osInfo.setHostName(address.getHostName());} catch (UnknownHostException e) {log.error("主机信息获取失败");}//系统启动时间osInfo.setBootTime(getBootTime());return osInfo;}public static void main(String[] args) throws Exception {//系统信息System.out.println("-----------系统信息-----------");OSInfo osInfo = getSystemInfo();System.out.println("操作系统:"+ osInfo.getOs());System.out.println("系统架构:"+ osInfo.getOsArch());System.out.println("Java版本:"+ osInfo.getJavaVersion());System.out.println("工作目录:"+ osInfo.getUserDir());System.out.println("cpu核心数:"+ osInfo.getCpuCount());System.out.println("主机host:"+ osInfo.getHost());System.out.println("主机名称:"+ osInfo.getHostName());String bootTime = osInfo.getBootTime();String runTime = "";if (StrUtil.isNotEmpty(bootTime)) {DateTime start = DateUtil.parse(bootTime, DatePattern.NORM_DATETIME_PATTERN);runTime = DateUtil.formatBetween(start, DateUtil.date());}System.out.println("系统正常运行时长:"+ runTime);//运行时信息System.out.println("-----------运行时信息-----------");OSRuntimeInfo osRuntimeInfo = getOSRuntimeInfo();//1.CPU信息System.out.println("------cpu信息------");System.out.println("cpu使用率:" + formatRate(osRuntimeInfo.getCpuUsage()));System.out.println("cpu基准速度:" + osRuntimeInfo.getCpuMaxFreq());System.out.println("cpu速度:" + osRuntimeInfo.getCpuCurrentFreq());//2.内存信息System.out.println("------内存信息------");//系统内存总量long total = osRuntimeInfo.getTotalMemory();long used = osRuntimeInfo.getUsedMemory();double usage = used * 1.0 / total;System.out.println("系统内存总量:" + total + " -> " + formatData(total));System.out.println("系统内存使用量:" + used + " -> " + formatData(used));System.out.println("系统内存使用率:" + formatRate(usage));//可用虚拟总内存long swapTotal = osRuntimeInfo.getSwapTotalMemory();//已用虚拟内存long swapUsed = osRuntimeInfo.getSwapUsedMemory();System.out.println("可用虚拟总内存(swap):" + swapTotal + " -> " + formatData(swapTotal));System.out.println("虚拟内存使用量(swap):" + swapUsed + " -> " + formatData(swapUsed));//3.磁盘信息System.out.println("------磁盘信息------");System.out.println("磁盘读取速度:" + osRuntimeInfo.getDiskReadRate() + "Kb/s");System.out.println("磁盘写入速度:" + osRuntimeInfo.getDiskWriteRate() + "Kb/s");List disksList = osRuntimeInfo.getDisksList();for (DisksInfo disksInfo : disksList) {System.out.println("挂载点:" + disksInfo.getDirName());System.out.println("文件系统名称:" + disksInfo.getSysTypeName());System.out.println("文件系统类型:" + disksInfo.getTypeName());System.out.println("磁盘总量:" + disksInfo.getTotal() + " -> " + formatData(disksInfo.getTotal()));System.out.println("磁盘使用量:" + disksInfo.getUsed() + " -> " + formatData(disksInfo.getUsed()));System.out.println("磁盘剩余量:" + disksInfo.getFree() + " -> " + formatData(disksInfo.getFree()));System.out.println("磁盘使用率:" + formatRate(disksInfo.getUsage()));}//4.网卡网络信息List netList = getNetworkInfo();System.out.println("------网卡网络信息------");for (NetworkInfo networkInfo : netList) {System.out.println("ipv4地址:"+networkInfo.getIpv4Address());System.out.println("mac地址:"+networkInfo.getMacAddress());System.out.println("网卡名称:"+networkInfo.getNetworkName());double send = networkInfo.getSend() / 1024.0;double accept = networkInfo.getAccept() / 1024.0;System.out.println("上传速度↑:"+String.format("%.1f%s", send, "Kbps"));System.out.println("下载速度↓:"+String.format("%.1f%s", accept, "Kbps"));}}/*** @return cpuRate cpu使用率* @throws InterruptedException*/public static double getCpuRate() throws InterruptedException {CentralProcessor processor = OshiUtil.getHardware().getProcessor();long[] prevTicks = processor.getSystemCpuLoadTicks();// 睡眠1sTimeUnit.SECONDS.sleep(1);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 = user + nice + cSys + idle + iowait + irq + softirq + steal;double d = 1.0 - (idle * 1.0 / totalCpu);return Double.parseDouble(df.format(d));}/*** 获取系统启动时间** @return*/public static String getBootTime() {String uptime = "";String os = System.getProperty("os.name").toLowerCase();try {if (os.contains("win")) {Process uptimeProc = Runtime.getRuntime().exec("net statistics Workstation");BufferedReader in = new BufferedReader(new InputStreamReader(uptimeProc.getInputStream(), Charset.forName("GBK")));String line;while ((line = in.readLine()) != null) {if (line.startsWith("Statistics since")) {SimpleDateFormat format = new SimpleDateFormat("'Statistics since' yyyy/MM/dd HH:mm:ss");Date bootTime = format.parse(line);uptime = DateUtil.format(bootTime, DatePattern.NORM_DATETIME_PATTERN);break;} else if (line.startsWith("统计数据开始于")) {SimpleDateFormat format = new SimpleDateFormat("'统计数据开始于' yyyy/MM/dd HH:mm:ss");Date bootTime = format.parse(line);uptime = DateUtil.format(bootTime, DatePattern.NORM_DATETIME_PATTERN);break;}}} else if (os.contains("mac") || os.contains("nix") || os.contains("nux") || os.contains("aix")) {Process uptimeProc = Runtime.getRuntime().exec("uptime -s");BufferedReader in = new BufferedReader(new InputStreamReader(uptimeProc.getInputStream()));String line = in.readLine();if (line != null) {uptime = line;}}} catch (Exception e) {log.error("获取系统启动时间异常: {}", e.getMessage());}return uptime;}/*** 获取磁盘读写速度(Kb/秒)** @return*/public static Map getDiskIo() {Map map = new HashMap<>();StringBuilder sb = new StringBuilder();String os = System.getProperty("os.name").toLowerCase();try {if (os.contains("mac") || os.contains("nix") || os.contains("nux") || os.contains("aix")) {Process pos = Runtime.getRuntime().exec("iostat -d 1 2");pos.waitFor();InputStreamReader isr = new InputStreamReader(pos.getInputStream());LineNumberReader lnr = new LineNumberReader(isr);String line;while ((line = lnr.readLine()) != null) {sb.append(line).append("\n");}}String info = sb.toString();if (StrUtil.isEmpty(info)) {map.put("diskReadRate", 0D);map.put("diskWriteRate", 0D);return map;}String[] data = info.split("\n");for (int i = 7; i < data.length; i++) {String[] numdata = data[i].split(" +");String devName = numdata[0];double diskReadRate = Double.parseDouble(numdata[2]); //磁盘读数据速率double diskWriteRate = Double.parseDouble(numdata[3]); //磁盘写数据速率//这里简单统计,只需要统计一个就行,直接break结束循环map.put("diskReadRate", diskReadRate);map.put("diskWriteRate", diskWriteRate);break;}} catch (Exception e) {map.put("diskReadRate", 0D);map.put("diskWriteRate", 0D);log.error("获取磁盘传输速度异常: {}", e.getMessage());}return map;}/*** 格式化输出百分比** @param rate 待格式化数据** * 0.1234 -> 12.34%* 1.2 -> 120%*
* @return*/public static String formatRate(double rate) {return new DecimalFormat("#.##%").format(rate);}/*** 格式化输出大小 B/KB/MB...** @param size 字节大小* @return*/public static String formatData(long size) {if (size <= 0L) {return "0B";} else {int digitGroups = Math.min(DataUnit.UNIT_NAMES.length - 1, (int) (Math.log10((double) size) / Math.log10(1024.0D)));return (new DecimalFormat("#,##0.##")).format((double) size / Math.pow(1024.0D, (double) digitGroups)) + " " + DataUnit.UNIT_NAMES[digitGroups];}}
}