/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.plugin.system; import org.hyperic.hq.product.LiveDataPlugin; import org.hyperic.hq.product.PluginException; import org.hyperic.hq.product.ProcessControlPlugin; import org.hyperic.hq.product.SigarMeasurementPlugin; import org.hyperic.sigar.Humidor; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarProxy; import org.hyperic.util.config.ConfigResponse; import com.thoughtworks.xstream.XStream; public class SystemLiveDataPlugin extends LiveDataPlugin { private static final int MAX_FILES = 500; public static final String PROP_PID = "process.pid"; public static final String PROP_SIGNAL = "process.signal"; public static final String PROP_NFILE = "read.numFiles"; public static final String PROP_FILE = "read.file."; public static final String PROP_OFFSET = "read.offset."; public static final String PROP_NUMBYTES = "read.numBytes."; private static final String CMD_TIME = "time"; private static final String CMD_READ = "read"; private static final String CMD_CPUINFO = "cpuinfo"; private static final String CMD_CPU = "cpu"; private static final String CMD_CPUPERC = "cpuperc"; private static final String CMD_DF = "df"; private static final String CMD_TOP = "top"; private static final String CMD_PROCESS = "process"; private static final String CMD_KILL = "kill"; private static final String CMD_NETSTAT = "netstat"; private static final String CMD_IFCONFIG = "ifconfig"; private static final String CMD_WHO = "who"; private static final String _COMMANDS[] = { CMD_TIME, CMD_READ, CMD_CPUINFO, CMD_CPU, CMD_CPUPERC, CMD_DF, CMD_TOP, CMD_PROCESS, CMD_KILL, CMD_NETSTAT, CMD_IFCONFIG, CMD_WHO }; private Sigar _sigarImpl; private Humidor _humidor; public void shutdown() throws PluginException { super.shutdown(); if (_sigarImpl != null) { _sigarImpl.close(); _sigarImpl = null; } } private ReadData getReadData(String file, String sOffset, String sNumBytes) throws PluginException { long offset; int numBytes; if (file == null || sOffset == null || sNumBytes == null) { throw new PluginException("Must specify " + PROP_FILE + ", " + PROP_OFFSET + ", " + PROP_NUMBYTES); } try { offset = Long.parseLong(sOffset); } catch(NumberFormatException e) { throw new PluginException("Invalid offset: " + sOffset); } try { numBytes = Integer.parseInt(sNumBytes); } catch(NumberFormatException e) { throw new PluginException("Invalid numBytes: " + sNumBytes); } return ReadData.gather(file, offset, numBytes); } private ReadData[] getReadData(ConfigResponse config) throws PluginException { String sNumFiles = config.getValue(PROP_NFILE); int numFiles; try { numFiles = Integer.parseInt(sNumFiles); } catch(NumberFormatException e) { throw new PluginException("Invalid " + PROP_NFILE, e); } if (numFiles > MAX_FILES) { throw new PluginException("Too many files. Max=" + MAX_FILES); } ReadData[] res = new ReadData[numFiles]; for (int i=0; i<numFiles; i++) { String file = config.getValue(PROP_FILE + i); String sOffset = config.getValue(PROP_OFFSET + i); String sNumBytes = config.getValue(PROP_NUMBYTES + i); res[i] = getReadData(file, sOffset, sNumBytes); } return res; } private long getPid(ConfigResponse config) throws PluginException { String pid = config.getValue(PROP_PID); if (pid == null) { throw new PluginException("Missing " + PROP_PID); } try { return Long.parseLong(pid); } catch (NumberFormatException e) { throw new PluginException("Invalid pid: " + pid); } } private synchronized SigarProxy getSigar() { if (_humidor == null) { _sigarImpl = new Sigar(); _humidor = new Humidor(_sigarImpl); } return _humidor.getSigar(); } public Object getData(String command, ConfigResponse config) throws PluginException { SigarProxy sigar = getSigar(); try { if (command.equals(CMD_TIME)) { return new TimeData(System.currentTimeMillis()); } else if (command.equals(CMD_READ)) { return getReadData(config); } else if (command.equals(CMD_CPUINFO)) { return sigar.getCpuInfoList(); } else if (command.equals(CMD_CPU)) { return sigar.getCpuList(); } else if (command.equals(CMD_CPUPERC)) { return sigar.getCpuPercList(); } else if (command.equals(CMD_DF)) { return DfData.gather(sigar); } else if (command.equals(CMD_TOP)) { String filter = config.getValue(SigarMeasurementPlugin.PTQL_CONFIG); return TopData.gather(sigar, filter); } else if (command.equals(CMD_PROCESS)) { return ProcessDetailData.gather(sigar, getPid(config)); } else if (command.equals(CMD_KILL)) { String signame = config.getValue(PROP_SIGNAL); if (signame == null) { signame = ProcessControlPlugin.SIGKILL; } long pid = getPid(config); int signal = ProcessControlPlugin.getSignal(signame); _sigarImpl.kill(pid, signal); return null; } else if (command.equals(CMD_NETSTAT)) { NetstatData data = new NetstatData(); String flags = config.getValue("netstat.flags"); if (flags != null) { data.setFlags(flags); } data.populate(sigar); return data; } else if (command.equals(CMD_IFCONFIG)) { return IfconfigData.gather(sigar); } else if (command.equals(CMD_WHO)) { return sigar.getWhoList(); } else { throw new PluginException("Unknown command '" + command + "'"); } } catch (SigarException e) { throw new PluginException("Error getting system data", e); } } public String[] getCommands() { return _COMMANDS; } public static void main(String[] args) throws Exception { SystemLiveDataPlugin p = new SystemLiveDataPlugin(); ConfigResponse emtpy = new ConfigResponse(); for (int i = 0; i < _COMMANDS.length; i++) { System.out.println("Running command " + _COMMANDS[i]); Object o = p.getData(_COMMANDS[i], emtpy); XStream xstream = new XStream(); System.out.println(xstream.toXML(o)); } } }