如何使用SIGAR远程获取另一台机器的系统信息?

时间:2012-06-11 17:41:37

标签: java jmx sigar

我正在开发一个项目,该项目需要显示CPU使用情况以及远程计算机的其他系统信息。 人们建议使用SIGAR来实现这一目标,但我不知道如何使用它。源代码对我来说没有多大意义。 基本上,我的问题是:当提供主机IP和JMX端口时,如何将SIGAR提供的MBean注册到服务器,以及如何从其他计算机获取系统信息。 如果我对JMX的工作原理有误,请纠正我。提前谢谢。

3 个答案:

答案 0 :(得分:0)

在我看来,您必须编写一些包装对象,以将各种SIGAR输出公开为JMX mbean属性。你如何做到这一点很大程度上取决于你使用什么来公开你的JMX bean。我会为各种不同类型的SIGAR输出编写一个包装对象:内存,磁盘......

我写了SimpleJMX library可能有所帮助。我将使用其格式提供一个示例对象,您可以使用它来通过JMX公开信息。您可以根据用于发布JMX方法的任何机制进行调整。我不熟悉SIGAR足以知道下面的sigar代码是否正确以获得ProcMem实例。

@JmxResource(description = "Show SIGAR Info", domainName = "foo")
public class SigarProcMem {

    private ProcMem procMem;

    {
      // sorry, I'm not up on sigar so I'm not sure if this works
      Sigar sigar = new Sigar();
      procMem = sigar.getProcMem(sigar.getPid());
    }

    @JmxAttributeMethod(description = "Resident memory")
    public long residentMemory() {
       return procMem.getResident();
    }

    @JmxAttributeMethod(description = "Get the Total process virtual memory")
    public long totalVirtualMemory() {
       return procMem.getSize();
    }
}

答案 1 :(得分:0)

这些是您可以注册的MBean中构建的Sigar类的名称:

  • org.hyperic.sigar.jmx.SigarCpu
  • org.hyperic.sigar.jmx.SigarCpuInfo
  • org.hyperic.sigar.jmx.SigarCpuPerc
  • org.hyperic.sigar.jmx.SigarLoadAverage
  • org.hyperic.sigar.jmx.SigarMem
  • org.hyperic.sigar.jmx.SigarProcess
  • org.hyperic.sigar.jmx.SigarRegistry
  • org.hyperic.sigar.jmx.SigarSwap

然而,远程部署这些将非常复杂,因为Sigar依赖于本地库,当加载MBean时,该库必须位于目标JVM的lib-path中。这意味着,您需要在要监视的每个目标主机上主动加载库和MBean。

您可能能够通过远程调用来破解目标JVM加载它的方法,但这非常重要,并且需要您绕过JVM中的任何安全设置,因为默认情况下,这是您的'不应该做的。

答案 2 :(得分:0)

您可以通过破解系统部分来轻松部署Sigjar:

private String before;
private Sigar sigar;

/**
 * Constructor - don't forget to call unload later!
 */
public SetlogSigar() throws Exception {
    before = System.getProperty("java.library.path");

    String path = "";

    String add = getJarFolder();

    if (before.contains(";"))
        path = before + ";./;" + add;
    else
        path = before + ":./:" + add;

    setSystemPath(path);

    sigar = new Sigar();

}

/**
 * This is needed to dynamically update the JAVA Path environment in order to load the needed native library
 * Yes -rather an ugly hack...
 */
private String getJarFolder() {
    // get name and path
    String path = SetlogSigar.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    String decodedPath = path;
    try {
        decodedPath = URLDecoder.decode(path, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return null;
    }    

    File f = new File(decodedPath);
    String absolutePath = f.getParentFile().getParentFile().getParentFile().getParent()+"/lib";

    return absolutePath;
}

/**
 * Unloads the JNI bindings
 */
public void unload() {
    this.sigar.close();
    setSystemPath(before);
}

此hack动态地将sigjar.jar所在的文件夹添加到环境变量中。只需将所有本机库放在那里,部署就不那么复杂了。