sigar
记录原因:前段时间项目需要监控服务器的硬件运行状态信息,因此了解了Sigar,网络上例子很多。但是sigar在不同系统上使用的库文件不一样,所以需要动态设置环境变量,故此记录一下这个问题。
再补充一个坑:java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Mem.gather(Lorg/hyperic/sigar/Sigar;)
排查到原因:环境变量中有两个带sigar依赖包的目录,所以sigar的依赖包不能多次设置到环境变量中。
简介
Sigar是Hyperic-hq产品的基础包,是Hyperic HQ主要的数据收集组件。它用来从许多平台收集系统和处理信息.
这些平台包括:Linux, Windows, Solaris, AIX, HP-UX, FreeBSD and Mac OSX.
Sigar有C,C#,Java和Perl API,java版的API为sigar.jar sigar.jar的底层是用C语言编写的,它通过本地方法来调用操作系统API来获取系统相关数据。
使用方式
1.Maven依赖下载
<dependency>
<groupId>org.fusesource</groupId>
<artifactId>sigar</artifactId>
<version>1.6.4</version>
</dependency>
2.本地引入
下载地址:https://sourceforge.net/projects/sigar/files/latest/download
直接拷贝下载压缩包中的Sigar.jar 到你的项目lib目录
(但是因为我们遇到的问题,所以需要动态加载jar包,就不需要放到lib里面了)
与普通jar包不同,Sigar API还要依赖本地的库文件来进行工作,其中:
Windows下Sigar.jar 依赖:sigar-amd64-winnt.dll 或 sigar-x86-winnt.dll
Linux 下Sigar.jar依赖:libsigar-amd64-linux.so 或 libsigar-x86-linux.so
Sigar 通过java.library.path加载这些本地库文件,这些库文件同样可以在下载的压缩包中找到,官方给出的库文件更多,可以根据自己的跨平台需要选择。
项目结构:
1.SigarUtils.java (动态设置环境变量工具类)
package com.org.lbl.sigar;
import java.io.File;
import org.hyperic.sigar.Sigar;
/**
* 类说明:动态设置环境变量
*
* @author libl
*
*/
public class SigarUtils {
public final static Sigar sigar = initSigar();
public static Sigar initSigar() {
try {
File classPath = new File(SigarUtils.class.getClassLoader().getResource("").getPath()+ File.separator + "sys");
String path = System.getProperty("java.library.path");
String sigarLibPath = classPath.getCanonicalPath();
// 为防止java.library.path重复加,此处判断了一下
if (!path.contains(sigarLibPath)) {
if (isOSWin()) {
path += ";" + sigarLibPath;
} else {
path += ":" + sigarLibPath;
}
System.setProperty("java.library.path", path);
}
return new Sigar();
} catch (Exception e) {
return null;
}
}
public static boolean isOSWin() {
// OS 系统判断
String OS = System.getProperty("os.name").toLowerCase();
if (OS.indexOf("win") >= 0) {
return true;
} else
return false;
}
}
2.HardWare.java(服务器硬件资源信息实体类)
package com.org.lbl.sigar;
import java.util.Date;
/**
* 类说明:服务器硬件资源
*
* @author libl
*
*/
public class HardWare {
private double cpuUsed; // cpu使用率
private Long memoryTotal; // 物理内存大小
private Long memoryUsed; // 物理内存使用大小
private Long diskTotal; // 磁盘总容量
private Long diskUsed; // 磁盘使用量
private Date checkTime; // 检测时间
public double getCpuUsed() {
return cpuUsed;
}
public void setCpuUsed(double cpuUsed) {
this.cpuUsed = cpuUsed;
}
public Long getMemoryTotal() {
return memoryTotal;
}
public void setMemoryTotal(Long memoryTotal) {
this.memoryTotal = memoryTotal;
}
public Long getMemoryUsed() {
return memoryUsed;
}
public void setMemoryUsed(Long memoryUsed) {
this.memoryUsed = memoryUsed;
}
public Long getDiskTotal() {
return diskTotal;
}
public void setDiskTotal(Long diskTotal) {
this.diskTotal = diskTotal;
}
public Long getDiskUsed() {
return diskUsed;
}
public void setDiskUsed(Long diskUsed) {
this.diskUsed = diskUsed;
}
public Date getCheckTime() {
return checkTime;
}
public void setCheckTime(Date checkTime) {
this.checkTime = checkTime;
}
@Override
public String toString() {
return "HardWare [cpuUsed=" + cpuUsed + ", memoryTotal=" + memoryTotal + ", memoryUsed=" + memoryUsed
+ ", diskTotal=" + diskTotal + ", diskUsed=" + diskUsed + ", checkTime=" + checkTime + "]";
}
}
3.HardWareInfo.java (获取服务器硬件资源检测信息)
package com.org.lbl.sigar;
import java.text.DecimalFormat;
import java.util.Date;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 类说明:服务器硬件资源检测信息
*
* @author libl
*
*/
public class HardWareInfo {
private static Logger LOG = LoggerFactory.getLogger(HardWareInfo.class);
private Sigar sigar = SigarUtils.sigar;
public HardWare getHardWare() {
LOG.info("开始检测硬件信息");
HardWare hardWare = null;
try {
hardWare = new HardWare();
hardWare.setCheckTime(new Date());
// 物理内存
Mem mem = sigar.getMem();
hardWare.setMemoryTotal(mem.getTotal() / 1024 / 1024);
hardWare.setMemoryUsed(mem.getUsed() / 1024 / 1024);
// 磁盘空间
hardWare.setDiskTotal(getDiskInfo()[0] / 1024);
hardWare.setDiskUsed(getDiskInfo()[