使用OSHI我们可以对应用程序进行监控,可以对应用程序所在的服务器资源进行监控,可以监控到很多的指标,如下:
1、计算机系统和固件,底板
2、操作系统和版本/内部版本 3、物理(核心)和逻辑(超线程)CPU,处理器组,NUMA节点 4、系统和每个处理器的负载百分比和滴答计数器 5、CPU正常运行时间,进程和线程 6、进程正常运行时间,CPU,内存使用率,用户/组,命令行 7、已使用/可用的物理和虚拟内存 8、挂载的文件系统(类型,可用空间和总空间) 9、磁盘驱动器(型号,序列号,大小)和分区 10、网络接口(IP,带宽输入/输出) 11、电池状态(电量百分比,剩余时间,电量使用情况统计信息) 12、连接的显示器(带有EDID信息) 13、USB设备 14、传感器(温度,风扇速度,电压)
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.9.1</version>
</dependency><dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>复制
java.lang.NoSuchMethodError:
com.sun.jna.platform.win32.WinNT$FILE_NOTIFY_INFORMATION.createFieldsOrder
([Ljava/lang/String;)Ljava/util/List;复制
之前在集成的时候遇到了很多的问题,参考了网上很多的答案,同时也收获到了更多不同的异常日志;
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.5.2</version>
</dependency>复制
当程序包的问题解决后,即可开始编写代码了;后续的代码跟网上的代码都是一样的,也都是从网上cv过来的;
import cn.hutool.core.util.NumberUtil;
import lombok.Data;
import java.io.Serializable;@Data
public class Cpu implements Serializable {
private static final long serialVersionUID = 1L;/**
* 核心数
*/
private int cpuNum;/**
* CPU总的使用率
*/
private double total;/**
* CPU系统使用率
*/
private double sys;/**
* CPU用户使用率
*/
private double used;/**
* CPU当前等待率
*/
private double wait;/**
* CPU当前空闲率
*/
private double free;public double getTotal() {
return NumberUtil.round(NumberUtil.mul(total, 100), 2).doubleValue();
}
public double getSys() {
return NumberUtil.round(NumberUtil.mul(sys / total, 100), 2).doubleValue();
}
public double getUsed() {
return NumberUtil.round(NumberUtil.mul(used / total, 100), 2).doubleValue();
}
public double getWait() {
return NumberUtil.round(NumberUtil.mul(wait / total, 100), 2).doubleValue();
}
public double getFree() {
return NumberUtil.round(NumberUtil.mul(free / total, 100), 2).doubleValue();
}
}复制
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.Data;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.util.Date;@Data
public class Jvm implements Serializable {
private static final long serialVersionUID = 1L;/**
* 当前JVM占用的内存总数(M)
*/
private double total;/**
* JVM最大可用内存总数(M)
*/
private double max;/**
* JVM空闲内存(M)
*/
private double free;/**
* JDK版本
*/
private String version;/**
* JDK路径
*/
private String home;public double getTotal() {
return NumberUtil.div(total, (1024 * 1024), 2);
}
public double getMax() {
return NumberUtil.div(max, (1024 * 1024), 2);
}
public double getFree() {
return NumberUtil.div(free, (1024 * 1024), 2);
}
public double getUsed() {
return NumberUtil.div(total - free, (1024 * 1024), 2);
}
public String getVersion() {
return version;
}
public String getHome() {
return home;
}
public double getUsage() {
return NumberUtil.mul(NumberUtil.div(total - free, total, 4), 100);
}
/**
* 获取JDK名称
*/
public String getName() {
return ManagementFactory.getRuntimeMXBean().getVmName();
}
/**
* JDK启动时间
*/
public String getStartTime() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time);
return DateUtil.formatDateTime(date);
}
/**
* JDK运行时间
*/
public String getRunTime() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time);//运行多少分钟
long runMS = DateUtil.between(date, new Date(), DateUnit.MS);long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;long day = runMS / nd;
long hour = runMS % nd / nh;
long min = runMS % nd % nh / nm;
return day + "天" + hour + "小时" + min + "分钟";
}
}复制
import cn.hutool.core.util.NumberUtil;
import lombok.Data;
import java.io.Serializable;@Data
public class Mem implements Serializable {
private static final long serialVersionUID = 1L;/**
* 内存总量
*/
private double total;/**
* 已用内存
*/
private double used;/**
* 剩余内存
*/
private double free;public double getTotal() {
return NumberUtil.div(total, (1024 * 1024 * 1024), 2);
}
public double getUsed() {
return NumberUtil.div(used, (1024 * 1024 * 1024), 2);
}
public double getFree() {
return NumberUtil.div(free, (1024 * 1024 * 1024), 2);
}
public double getUsage() {
return NumberUtil.mul(NumberUtil.div(used, total, 4), 100);
}
}复制
import lombok.Data;
import java.io.Serializable;@Data
public class Sys implements Serializable {
private static final long serialVersionUID = 1L;/**
* 服务器名称
*/
private String computerName;/**
* 服务器Ip
*/
private String computerIp;/**
* 项目路径
*/
private String userDir;/**
* 操作系统
*/
private String osName;/**
* 系统架构
*/
private String osArch;
}复制
import lombok.Data;
import java.io.Serializable;@Data
public class SysFile implements Serializable {
private static final long serialVersionUID = 1L;/**
* 盘符路径
*/
private String dirName;/**
* 盘符类型
*/
private String sysTypeName;/**
* 文件类型
*/
private String typeName;/**
* 总大小
*/
private String total;/**
* 剩余大小
*/
private String free;/**
* 已经使用量
*/
private String used;/**
* 资源的使用率
*/
private double usage;
}复制
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.NumberUtil;
import com.gw.ard.common.tools.IpUtil;
import lombok.Data;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;@Data
public class SystemHardwareInfo implements Serializable {
private static final long serialVersionUID = 1L;private static final int OSHI_WAIT_SECOND = 1000;
/**
* CPU相关信息
*/
private Cpu cpu = new Cpu();/**
* 內存相关信息
*/
private Mem mem = new Mem();/**
* JVM相关信息
*/
private Jvm jvm = new Jvm();/**
* 服务器相关信息
*/
private Sys sys = new Sys();/**
* 磁盘相关信息
*/
private List<SysFile> sysFiles = new LinkedList<SysFile>();public void copyTo() throws Exception {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor) {
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu);
cpu.setSys(cSys);
cpu.setUsed(user);
cpu.setWait(iowait);
cpu.setFree(idle);
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory) {
mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable());
}
/**
* 设置服务器信息
*/
private void setSysInfo() {
Properties props = System.getProperties();
sys.setComputerName(IpUtil.getHostName());
sys.setComputerIp(NetUtil.getLocalhostStr());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() {
Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory());
jvm.setFree(Runtime.getRuntime().freeMemory());
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os) {
FileSystem fileSystem = os.getFileSystem();
OSFileStore[] fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray) {
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(NumberUtil.round(NumberUtil.mul(used, total, 4), 100).doubleValue());
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size) {
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb) {
return String.format("%.1f GB" , (float) size / gb);
} else if (size >= mb) {
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB" , f);
} else if (size >= kb) {
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB" , f);
} else {
return String.format("%d B" , size);
}
}
}复制
这样,只需要调用当前类的copyTo()方法即可获取到数据信息;
踩坑比较多,不过最终定位踩坑的主要原因在于jar包的版本上,大家只要注意好jar包的版本后,基本上就可以跳过很多坑了;
还有,如果我们是分布式项目的话,使用oshi也可以监听到分布式项目的所有的节点,见下一章节dubbo的远程Rpc调用;
2020年6月16日 18:24:42
文章转载自加耀,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1320次阅读
2025-03-13 11:40:53
【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化
墨天轮编辑部
1299次阅读
2025-03-06 16:45:38
2025年2月国产数据库大事记
墨天轮编辑部
1020次阅读
2025-03-05 12:27:34
2025年2月国产数据库中标情况一览:GoldenDB 3500+万!达梦近千万!
通讯员
902次阅读
2025-03-06 11:40:20
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
462次阅读
2025-03-13 14:38:19
AI的优化能力,取决于你问问题的能力!
潇湘秦
437次阅读
2025-03-11 11:18:22
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
344次阅读
2025-03-21 10:34:08
达梦数据与法本信息签署战略合作协议
达梦数据
297次阅读
2025-03-06 09:26:57
国产化+性能王炸!这套国产方案让 3.5T 数据 5 小时“无感搬家”
YMatrix
284次阅读
2025-03-13 09:51:26
磐维数据库对外门户全新升级!
磐维数据库
244次阅读
2025-03-04 15:32:59
热门文章
【ElasticSearch进阶】理解Elasticsearch词频归一值BM25计算公式
2020-09-22 2544浏览
Druid 简单介绍和配置及使用
2018-11-18 2503浏览
Elasticsearch7.8实现random随机排序查询(Java)
2020-09-23 2346浏览
Canal-adapter1.1.4集成Elasticsearch7.8.0排坑指南及在本地环境运行canal-adapter项
2021-03-07 2325浏览
【网络安全】接口数据完整性校验及重放攻击防御可行性方案分析
2020-01-25 1650浏览
最新文章
关于Java线程池的7个参数说明及配置参考
2021-07-29 785浏览
Elasticsearch实现类主流搜索引擎广告置顶效果 及其 java代码实现pinned语法案例
2021-05-17 858浏览
Canal-adapter1.1.4集成Elasticsearch7.8.0排坑指南及在本地环境运行canal-adapter项
2021-03-07 2325浏览
Elasticsearch7.8.0集成IK分词器改源码实现MySql5.7.2实现动态词库实时更新
2020-10-24 1350浏览
Elasticsearch7.8.0查询高亮显示java代码示例
2020-09-25 1182浏览