package kg.apc.perfmon.metrics; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; import org.hyperic.sigar.ProcExe; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarProxy; import org.hyperic.sigar.ptql.ProcessFinder; import java.io.File; import java.util.HashMap; import java.util.List; /** * Class to parse metric params like process name, PID, metric type * * @author undera */ public class MetricParamsSigar extends MetricParams { private static final Logger log = LoggingManager.getLoggerForClass(); private final SigarProxy sigar; static MetricParamsSigar createFromString(String metricParamsStr, SigarProxy sigarProxy) { MetricParamsSigar inst = new MetricParamsSigar(sigarProxy); parseParams(metricParamsStr, inst); return inst; } protected MetricParamsSigar(SigarProxy sigarProxy) { sigar = sigarProxy; } protected void populateParams(String token, List params) throws NumberFormatException { if (token.startsWith("name=")) { this.PID = getPIDByName(token); } else if (token.startsWith("ptql=")) { this.PID = getPIDByPTQL(token); } else { super.populateParams(token, params); } } private long getPIDByName(String token) { String name = token.substring(token.indexOf("=") + 1); String[] parts = name.split("#"); try { long index = parts.length > 1 ? Long.parseLong(parts[1]) : 0; PID = getPIDByProcName(parts[0], index); if (PID <= 0) { log.warn("Unable to find process from name: " + name); } } catch (ArrayIndexOutOfBoundsException e) { log.warn("Error processing token: " + token, e); PID = -1; } catch (NumberFormatException e) { log.warn("Error processing token: " + token, e); PID = -1; } return PID; } private long getPIDByPTQL(String token) { String query = token.substring(token.indexOf("=") + 1); try { final ProcessFinder finder = new ProcessFinder(sigar); long[] pids = finder.find(query); if (pids.length < 1) { log.warn("Unable to find process from query: " + query); return -1; } else { return pids[0]; } } catch (SigarException ex) { log.warn("Error querying PTQL: " + query, ex); return -1; } } private long getPIDByProcName(String name, long index) { int procIndex = 0; long[] list; ProcExe proc; try { list = sigar.getProcList(); } catch (SigarException ex) { log.error("Failed to get process list", ex); return -1; } for (int n = 0; n < list.length; n++) { try { proc = sigar.getProcExe(list[n]); } catch (SigarException e) { log.debug("Can't get process exe for pid " + list[n], e); continue; } // case insensitive match String pname = proc.getName().toLowerCase(); if (pname.endsWith(File.separator + name.toLowerCase())) { if (procIndex == index) { return list[n]; } procIndex++; } } return -1; } static void logAvailableProcesses(SigarProxy sigar) { log.info("*** Logging available processes ***"); long[] list = new long[0]; try { list = sigar.getProcList(); } catch (SigarException ex) { log.error("Failed to get process list", ex); } HashMap nameMap = new HashMap(); ProcExe proc; for (int n = 0; n < list.length; n++) { try { proc = sigar.getProcExe(list[n]); } catch (SigarException e) { log.debug("Can't get process exe for pid " + list[n], e); continue; } StringBuffer str = new StringBuffer("Process: "); str.append("pid=").append(list[n]).append(' '); String pname = proc.getName().substring(proc.getName().lastIndexOf(File.separator) + 1).toLowerCase(); str.append("name=").append(pname); if (nameMap.containsKey(pname)) { Long val = (Long) nameMap.get(pname); val = new Long(val.longValue() + 1); nameMap.put(pname, val); str.append('#').append(val); } else { nameMap.put(pname, new Long(0)); } try { String[] args = sigar.getProcArgs(list[n]); str.append(" args="); join(str, args, " "); } catch (SigarException ex) { log.debug("Can't get process args for pid " + list[n], ex); } log.info(str.toString()); } } }