系统信息采集方面,选择使用Sigar的第三方库。
对于Sigar做一个简单的梳理。
服务器监控,一方面要对游戏服务器的数据进行采集,另一方面也要对游戏服务器所在的系统信息进行采集。我打算使用sigar来获取系统信息的采集工作。其Demo非常完整,并且跨平台支持,本身对于.net,C++,php,python,java,perl,ruby都是支持的,为以后的扩展和更改留有很多的余地。
sigar网址:https://support.hyperic.com/display/SIGAR/Home;jsessionid=93D9F25FC4BE420D102F15793F9EF0E1
sigar本身是带log4j的日志框架
sigar的Java实现主要还是调用本地的库,所以需要根据不同的平台引入相应的本地库。例如windows平台,就应当在构建工程的时候设置NativeLib:sigar-x86-winnt.dll、sigar-x86-winnt.lib、sigar-amd64-winnt
并引入sigar.jar,看一个官方获取系统信息的代码:
/* * Copyright (c) 2006-2009 Hyperic, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hyperic.sigar.cmd; import java.io.File; import java.io.PrintStream; import java.net.InetAddress; import java.net.UnknownHostException; import org.hyperic.sigar.OperatingSystem; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarLoader; import org.hyperic.sigar.win32.LocaleInfo; /** * Display Sigar, java and system version information. */ public class Version extends SigarCommandBase { public Version(Shell shell) { super(shell); } public Version() { super(); } public String getUsageShort() { return "Display sigar and system version info"; } private static String getHostName() { try { return InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { return "unknown"; } } private static void printNativeInfo(PrintStream os) { String version = "java=" + Sigar.VERSION_STRING + ", native=" + Sigar.NATIVE_VERSION_STRING; String build = "java=" + Sigar.BUILD_DATE + ", native=" + Sigar.NATIVE_BUILD_DATE; String scm = "java=" + Sigar.SCM_REVISION + ", native=" + Sigar.NATIVE_SCM_REVISION; String archlib = SigarLoader.getNativeLibraryName(); os.println("Sigar version......." + version); os.println("Build date.........." + build); os.println("SCM rev............." + scm); String host = getHostName(); String fqdn; Sigar sigar = new Sigar(); try { File lib = sigar.getNativeLibrary(); if (lib != null) { archlib = lib.getName(); } fqdn = sigar.getFQDN(); } catch (SigarException e) { fqdn = "unknown"; } finally { sigar.close(); } os.println("Archlib............." + archlib); os.println("Current fqdn........" + fqdn); if (!fqdn.equals(host)) { os.println("Hostname............" + host); } if (SigarLoader.IS_WIN32) { LocaleInfo info = new LocaleInfo(); os.println("Language............" + info); os.println("Perflib lang id....." + info.getPerflibLangId()); } } public static void printInfo(PrintStream os) { try { printNativeInfo(os); } catch (UnsatisfiedLinkError e) { os.println("*******ERROR******* " + e); } os.println("Current user........" + System.getProperty("user.name")); os.println(""); OperatingSystem sys = OperatingSystem.getInstance(); os.println("OS description......" + sys.getDescription()); os.println("OS name............." + sys.getName()); os.println("OS arch............." + sys.getArch()); os.println("OS machine.........." + sys.getMachine()); os.println("OS version.........." + sys.getVersion()); os.println("OS patch level......" + sys.getPatchLevel()); os.println("OS vendor..........." + sys.getVendor()); os.println("OS vendor version..." + sys.getVendorVersion()); if (sys.getVendorCodeName() != null) { os.println("OS code name........" + sys.getVendorCodeName()); } os.println("OS data model......." + sys.getDataModel()); os.println("OS cpu endian......." + sys.getCpuEndian()); os.println("Java vm version....." + System.getProperty("java.vm.version")); os.println("Java vm vendor......" + System.getProperty("java.vm.vendor")); os.println("Java home..........." + System.getProperty("java.home")); } public void output(String[] args) { printInfo(this.out); } public static void main(String[] args) throws Exception { new Version().processCommand(args); } }
其他的信息获取也类似,均是采用单例的方式,但是在一些时候获取并不方便,需要我们根据具体的情况做一些上层的封装。但是已经很便捷了。并且sigar本身对于输出格式是可以进行设置,例如CPU相关信息的的百分制的方式。
private void output(CpuPerc cpu) { println("User Time....." + CpuPerc.format(cpu.getUser())); println("Sys Time......" + CpuPerc.format(cpu.getSys())); println("Idle Time....." + CpuPerc.format(cpu.getIdle())); println("Wait Time....." + CpuPerc.format(cpu.getWait())); println("Nice Time....." + CpuPerc.format(cpu.getNice())); println("Combined......" + CpuPerc.format(cpu.getCombined())); println("Irq Time......" + CpuPerc.format(cpu.getIrq())); if (SigarLoader.IS_LINUX) { println("SoftIrq Time.." + CpuPerc.format(cpu.getSoftIrq())); println("Stolen Time...." + CpuPerc.format(cpu.getStolen())); } println(""); }
并且Java的库主要是根据shell命令来进行区分的,非常的容易辨识,除此之外,官方Java例子还对Shell命令的跨平台进行了统一,带有官方Demo有兴趣可以去看下,但是已经不是下面提到的目录了,而是bingings/java/examples/Shell.java。
sigar本身的稳定性而言,应该不用过多的质疑。以下是一些项目使用了sigar采集系统信息的项目,足见其稳定性。