/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.resourcemonitor; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; import com.slamd.common.Constants; import com.slamd.common.SLAMDException; import com.slamd.job.JobClass; import com.slamd.stat.IntegerValueTracker; import com.slamd.stat.RealTimeStatReporter; import com.slamd.stat.StackedValueTracker; import com.slamd.stat.StatTracker; /** * This class defines a SLAMD resource monitor that uses the vmstat utility to * capture information about CPU utilization. * * * @author Neil A. Wilson */ public class VMStatResourceMonitor extends ResourceMonitor { /** * The display name of the stat tracker that will be used to report the CPU * busy time (user time + system time). */ public static final String STAT_TRACKER_CPU_BUSY = "CPU Busy Time"; /** * The display name of the stat tracker that will be used to report the CPU * idle time. */ public static final String STAT_TRACKER_CPU_IDLE = "CPU Idle Time"; /** * The display name of the stat tracker that will be used to report the CPU * system time. */ public static final String STAT_TRACKER_CPU_SYSTEM = "CPU System Time"; /** * The display name of the stat tracker that will be used to report the CPU * user time. */ public static final String STAT_TRACKER_CPU_USER = "CPU User Time"; /** * The display name of the stat tracker that will be used to report CPU * utilization, combining user, system, and idle times. */ public static final String STAT_TRACKER_CPU_UTILIZATION = "CPU Utilization"; /** * The display name of the stat tracker that will be used to report the amount * of free memory on the system as reported by vmstat. */ public static final String STAT_TRACKER_FREE_MEMORY = "Free Memory"; /** * The category name that will be used for reporting user time. */ public static final String UTILIZATION_CATEGORY_USER = "User Time"; /** * The category name that will be used for reporting system time. */ public static final String UTILIZATION_CATEGORY_SYSTEM = "System Time"; /** * The category name that will be used for reporting idle time. */ public static final String UTILIZATION_CATEGORY_IDLE = "Idle Time"; /** * The names of the categories into which CPU utilization will be divided. */ public static final String[] CPU_UTILIZATION_CATEGORIES = { UTILIZATION_CATEGORY_USER, UTILIZATION_CATEGORY_SYSTEM, UTILIZATION_CATEGORY_IDLE }; /** * The type of vmstat output that indicates that the client is a Linux system * that does not have a supported version of vmstat. */ public static final int LINUX_VMSTAT_TYPE_UNSUPPORTED = 0; /** * The type of vmstat output that indicates the client is a Linux system * with the version of vmstat used in the 2.x version of the procps package. */ public static final int LINUX_VMSTAT_TYPE_PROCPS_2 = 2; /** * The type of vmstat output that indicates the client is a Linux system with * the version of vmstat used in the 3.x version of the procps package. */ public static final int LINUX_VMSTAT_TYPE_PROCPS_3 = 3; /** * The type of vmstat output that indicates the client is a Linux system with * a version of vmstat like that used on Red Hat Enterprise 3.0. */ public static final int LINUX_VMSTAT_TYPE_RHEL_30 = 4; /** * The type of vmstat output that indicates the client is a Linux system with * a version of vmstat like that used on Red Hat Enterprise 5.0. */ public static final int LINUX_VMSTAT_TYPE_RHEL_50 = 5; /** * The name of the configuration property that indicates the path of the * vmstat command (or the path to a command that generates output in a * supported format for the current OS). */ public static final String PROPERTY_VMSTAT_COMMAND = "vmstat_command"; /** * The default vmstat command that will be executed if no alternative is * provided. */ public static final String DEFAULT_VMSTAT_COMMAND = "vmstat"; /** * The name of the configuration property that indicates whether to skip the * first line of actual vmstat data. In many cases, the fist line that vmstat * outputs is actually a summary of what has occurred since the system was * last booted, and does not actually reflect the current workload. */ public static final String PROPERTY_SKIP_FIRST_LINE = "skip_first_line"; /** * The default behavior that will be used with regards to skipping the first * line of output if no other value is provided. */ public static final boolean DEFAULT_SKIP_FIRST_LINE = true; /** * The name of the configuration property that indicates whether the * aggregate CPU utilization should be captured. */ public static final String PROPERTY_CAPTURE_CPU_UTILIZATION = "capture_cpu_utilization"; /** * The default behavior that will be used with regards to capturing aggregate * CPU utilization. */ public static final boolean DEFAULT_CAPTURE_CPU_UTILIZATION = true; /** * The name of the configuration property that indicates whether the CPU busy * (user+system) time should be captured. */ public static final String PROPERTY_CAPTURE_CPU_BUSY = "capture_cpu_busy"; /** * The default behavior that will be used with regards to capturing CPU busy * time. */ public static final boolean DEFAULT_CAPTURE_CPU_BUSY = true; /** * The name of the configuration property that indicates whether the CPU user * time should be captured. */ public static final String PROPERTY_CAPTURE_CPU_USER = "capture_cpu_user"; /** * The default behavior that will be used with regards to capturing CPU user * time. */ public static final boolean DEFAULT_CAPTURE_CPU_USER = true; /** * The name of the configuration property that indicates whether the CPU * system time should be captured. */ public static final String PROPERTY_CAPTURE_CPU_SYSTEM = "capture_cpu_system"; /** * The default behavior that will be used with regards to capturing CPU system * time. */ public static final boolean DEFAULT_CAPTURE_CPU_SYSTEM = true; /** * The name of the configuration property that indicates whether the CPU idle * time should be captured. */ public static final String PROPERTY_CAPTURE_CPU_IDLE = "capture_cpu_idle"; /** * The default behavior that will be used with regards to capturing CPU idle * time. */ public static final boolean DEFAULT_CAPTURE_CPU_IDLE = true; /** * The name of the configuration property that indicates whether the amount of * free memory should be captured. */ public static final String PROPERTY_CAPTURE_FREE_MEMORY = "capture_free_memory"; /** * The default behavior that will be used with regards to capturing the amount * of free memory. */ public static final boolean DEFAULT_CAPTURE_FREE_MEMORY = true; /** * The name of the configuration property that specifies minimum percentage of * CPU busy (user + system) time that may occur at any point during processing * at which a log message will be written to the SLAMD server. */ public static final String PROPERTY_PEAK_UTILIZATION_LOG_THRESHOLD = "peak_utilization_log_threshold"; /** * The default value that will be used as the peak utilization log threshold. */ public static final int DEFAULT_PEAK_UTILIZATION_LOG_THRESHOLD = -1; /** * The name of the configuration property that specifies minimum percentage of * CPU busy (user + system) time that may occur as the average over the * duration of the job at which a log message will be written to the SLAMD * server. */ public static final String PROPERTY_AVERAGE_UTILIZATION_LOG_THRESHOLD = "average_utilization_log_threshold"; /** * The default value that will be used as the average utilization log * threshold. */ public static final int DEFAULT_AVERAGE_UTILIZATION_LOG_THRESHOLD = -1; // Stat trackers that will be used by this resource monitor thread. private IntegerValueTracker cpuBusyTime; private IntegerValueTracker cpuIdleTime; private IntegerValueTracker cpuSystemTime; private IntegerValueTracker cpuUserTime; private IntegerValueTracker freeMemory; private StackedValueTracker cpuUtilization; // Flags that indicate what should be captured private boolean captureCPUBusy; private boolean captureCPUIdle; private boolean captureCPUSystem; private boolean captureCPUUser; private boolean captureCPUUtilization; private boolean captureFreeMemory; private int averageUtilizationLogThreshold; private int peakUtilizationLogThreshold; // A flag that indicates whether real-time statistics collection should be // enabled. private boolean enableRealTimeStats; // The array lists that will be used to hold the data collected while vmstat // is running. private ArrayList<Integer> freeMemoryList; private ArrayList<Integer> systemList; private ArrayList<Integer> userList; // Flags dealing with skipping the first line of output. private boolean firstLineSkipped; private boolean skipFirstLine; // The statistics collection interval that should be used. private int collectionInterval; // An indicator that specifies which type of vmstat we have on a linux system. private static int linuxVMStatType; // The type of OS on which this client is running. private int osType; // The actual command to execute in order to get the vmstat output. private String vmstatCommand; /** * Performs any initialization specific to this resource monitor. * * @throws SLAMDException If a problem occurs while performing the * initialization. */ @Override() public void initializeMonitor() throws SLAMDException { vmstatCommand = getProperty(PROPERTY_VMSTAT_COMMAND, DEFAULT_VMSTAT_COMMAND); skipFirstLine = getProperty(PROPERTY_SKIP_FIRST_LINE, DEFAULT_SKIP_FIRST_LINE); captureCPUUtilization = getProperty(PROPERTY_CAPTURE_CPU_UTILIZATION, DEFAULT_CAPTURE_CPU_UTILIZATION); captureCPUBusy = getProperty(PROPERTY_CAPTURE_CPU_BUSY, DEFAULT_CAPTURE_CPU_BUSY); captureCPUUser = getProperty(PROPERTY_CAPTURE_CPU_USER, DEFAULT_CAPTURE_CPU_USER); captureCPUSystem = getProperty(PROPERTY_CAPTURE_CPU_SYSTEM, DEFAULT_CAPTURE_CPU_SYSTEM); captureCPUIdle = getProperty(PROPERTY_CAPTURE_CPU_IDLE, DEFAULT_CAPTURE_CPU_IDLE); captureFreeMemory = getProperty(PROPERTY_CAPTURE_FREE_MEMORY, DEFAULT_CAPTURE_FREE_MEMORY); averageUtilizationLogThreshold = getProperty(PROPERTY_AVERAGE_UTILIZATION_LOG_THRESHOLD, DEFAULT_AVERAGE_UTILIZATION_LOG_THRESHOLD); peakUtilizationLogThreshold = getProperty(PROPERTY_PEAK_UTILIZATION_LOG_THRESHOLD, DEFAULT_PEAK_UTILIZATION_LOG_THRESHOLD); firstLineSkipped = false; osType = monitorClient.getClientOS(); userList = new ArrayList<Integer>(); systemList = new ArrayList<Integer>(); freeMemoryList = new ArrayList<Integer>(); } /** * Indicates whether the current client system is supported for this resource * monitor. * * @return <CODE>true</CODE> if the current client system is supported for * this resource monitor, or <CODE>false</CODE> if not. */ @Override() public boolean clientSupported() { int osType = getClientOS(); switch (osType) { case OS_TYPE_SOLARIS: return true; case OS_TYPE_LINUX: return linuxSupported(); case OS_TYPE_HPUX: return true; case OS_TYPE_AIX: return true; case OS_TYPE_WINDOWS: File vmstatFile = new File(vmstatCommand); if (vmstatFile.exists()) { // On Windows, the only supported version of vmstat must be provided // by Cygwin, and therefore will behave much like a Linux version. return linuxSupported(); } else { writeVerbose("vmstat is unsupported on Windows without a valid " + "vmstat_command configuration."); return false; } default: return false; } } /** * Indicates whether this job will be available on Linux. This is necessary * because some Linux systems may not come with vmstat and of those that do * there may be different styles of output. * * @return <CODE>true</CODE> if the current Linux client system has a * supported vmstat, or <CODE>false</CODE> if not. */ private boolean linuxSupported() { try { Process p = Runtime.getRuntime().exec(vmstatCommand); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); // First, see if it exited immediately with an illegal try { int exitValue = p.exitValue(); if (exitValue != 0) { writeVerbose("vmstat version not supported -- nonzero exit code " + exitValue); linuxVMStatType = LINUX_VMSTAT_TYPE_UNSUPPORTED; return false; } } catch (IllegalThreadStateException itse) { // No problem, the command hasn't exited yet. } String line = br.readLine(); if (line.equals("procs -----------memory---------- ---swap-- " + "-----io---- --system-- ----cpu----")) { linuxVMStatType = LINUX_VMSTAT_TYPE_PROCPS_3; try { br.close(); } catch (Exception e) {} writeVerbose("vmstat appears to be from procps 3"); return true; } else if (line.equals(" procs memory swap" + " io system cpu")) { linuxVMStatType = LINUX_VMSTAT_TYPE_PROCPS_2; try { br.close(); } catch (Exception e) {} writeVerbose("vmstat appears to be from procps 2"); return true; } else if (line.equals("procs memory swap" + " io system cpu")) { linuxVMStatType = LINUX_VMSTAT_TYPE_RHEL_30; try { br.close(); } catch (Exception e) {} writeVerbose("vmstat appears to be from RHEL 3.0"); return true; } else if (line.equals("procs -----------memory---------- ---swap-- " + "-----io---- --system-- -----cpu------")) { linuxVMStatType = LINUX_VMSTAT_TYPE_RHEL_50; try { br.close(); } catch (Exception e) {} writeVerbose("vmstat appears to be from RHEL 5.0"); return true; } else { linuxVMStatType = LINUX_VMSTAT_TYPE_UNSUPPORTED; try { br.close(); } catch (Exception e) {} writeVerbose("Unrecognized vmstat output cannot be supported"); writeVerbose("vmstat command output was: \"" + line + '"'); return false; } } catch (Exception e) { linuxVMStatType = LINUX_VMSTAT_TYPE_UNSUPPORTED; writeVerbose("Exception caught while parsing vmstat output: " + JobClass.stackTraceToString(e)); return false; } } /** * Creates a new instance of this resource monitor thread. Note that the * <CODE>initialize()</CODE> method should have been called on the new * instance before it is returned. * * @return A new instance of this resource monitor thread. * * @throws SLAMDException If a problem occurs while creating or initializing * the resource monitor. */ @Override() public ResourceMonitor newInstance() throws SLAMDException { VMStatResourceMonitor monitor = new VMStatResourceMonitor(); monitor.initialize(getMonitorClient(), getMonitorProperties()); return monitor; } /** * Initializes the stat trackers maintained by this resource monitor. * * @param clientID The client ID to use for the stubs. * @param threadID The thread ID to use for the stubs. * @param collectionInterval The collection interval to use for the stubs. */ @Override() public void initializeStatistics(String clientID, String threadID, int collectionInterval) { this.collectionInterval = collectionInterval; // We may not actually capture all this data, but it won't hurt to // initialize it anyway. cpuIdleTime = new IntegerValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_CPU_IDLE, collectionInterval); cpuSystemTime = new IntegerValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_CPU_SYSTEM, collectionInterval); cpuUserTime = new IntegerValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_CPU_USER, collectionInterval); cpuBusyTime = new IntegerValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_CPU_BUSY, collectionInterval); cpuUtilization = new StackedValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_CPU_UTILIZATION, collectionInterval, CPU_UTILIZATION_CATEGORIES); freeMemory = new IntegerValueTracker(clientID, threadID, clientID + ' ' + STAT_TRACKER_FREE_MEMORY, collectionInterval); cpuUtilization.setDrawAsStackedGraph(true); cpuUtilization.setIncludeLegend(true); } /** * Retrieves the name to use for this resource monitor. * * @return The name to use for this resource monitor. */ @Override() public String getMonitorName() { return "VMStat"; } /** * Retrieves the statistical data collected by this resource monitor. * * @return The statistical data collected by this resource monitor. */ @Override() public StatTracker[] getResourceStatistics() { ArrayList<StatTracker> statList = new ArrayList<StatTracker>(); if (captureCPUUtilization) { statList.add(cpuUtilization); } if (captureCPUBusy) { statList.add(cpuBusyTime); } if (captureCPUUser) { statList.add(cpuUserTime); } if (captureCPUSystem) { statList.add(cpuSystemTime); } if (captureCPUIdle) { statList.add(cpuIdleTime); } if (captureFreeMemory) { statList.add(freeMemory); } StatTracker[] returnTrackers = new StatTracker[statList.size()]; statList.toArray(returnTrackers); return returnTrackers; } /** * Performs the work of actually collecting resource statistics. This method * should periodically call the <CODE>shouldStop()</CODE> method to determine * whether to stop collecting statistics. * * @return A value that indicates the status of the monitor when it * completed. */ @Override() public int runMonitor() { // Determine whether to enable real-time statistics collection. If so, then // we'll actually capture the data twice -- once for real-time reporting and // then again for what we actually report back to the server. ResourceMonitorJob monitorJob = getMonitorJob(); if ((monitorJob != null) && (monitorJob.enableRealTimeStats())) { String jobID = monitorJob.getJobID(); RealTimeStatReporter statReporter = monitorJob.getStatReporter(); enableRealTimeStats = true; if (captureCPUUser) { cpuUserTime.startTracker(); cpuUserTime.enableRealTimeStats(statReporter, jobID); } if (captureCPUSystem) { cpuSystemTime.startTracker(); cpuSystemTime.enableRealTimeStats(statReporter, jobID); } if (captureCPUIdle) { cpuIdleTime.startTracker(); cpuIdleTime.enableRealTimeStats(statReporter, jobID); } if (captureCPUBusy) { cpuBusyTime.startTracker(); cpuBusyTime.enableRealTimeStats(statReporter, jobID); } if (captureFreeMemory) { freeMemory.startTracker(); freeMemory.enableRealTimeStats(statReporter, jobID); } } // First execute the vmstat command and collect its output. Process p; InputStream inputStream; BufferedReader reader; try { String[] commandArray = { vmstatCommand, String.valueOf(collectionInterval) }; p = Runtime.getRuntime().exec(commandArray); inputStream = p.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); } catch (Exception e) { logMessage("Error executing command \"" + vmstatCommand + ' ' + collectionInterval + "\" -- " + e); return Constants.JOB_STATE_STOPPED_DUE_TO_ERROR; } int stopReason = Constants.JOB_STATE_COMPLETED_SUCCESSFULLY; while (! shouldStop()) { try { if (inputStream.available() == 0) { try { Thread.sleep(10); } catch (InterruptedException ie) {} continue; } String line = reader.readLine(); if (line == null) { // The command stopped running for some reason. logMessage("Command \"" + vmstatCommand + ' ' + collectionInterval + "\" stopped producing output."); stopReason = Constants.JOB_STATE_COMPLETED_WITH_ERRORS; break; } else { switch (osType) { case OS_TYPE_SOLARIS: parseSolarisLine(line); break; case OS_TYPE_LINUX: parseLinuxLine(line); break; case OS_TYPE_HPUX: parseHPUXLine(line); break; case OS_TYPE_AIX: parseAIXLine(line); break; case OS_TYPE_WINDOWS: // On Windows, if we're using Cygwin then the output should look // like it does on Linux. parseLinuxLine(line); break; } } } catch (Exception e) { logMessage("Error while parsing output of command \"" + vmstatCommand + ' ' + collectionInterval + "\" -- " + e); stopReason = Constants.JOB_STATE_COMPLETED_WITH_ERRORS; } } try { reader.close(); p.destroy(); } catch (Exception e) {} // If we were capturing real-time statistics, then stop so that we can // replace the data with what will actually be reported. if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.stopTracker(); } if (captureCPUSystem) { cpuSystemTime.stopTracker(); } if (captureCPUIdle) { cpuIdleTime.stopTracker(); } if (captureCPUBusy) { cpuBusyTime.stopTracker(); } if (captureFreeMemory) { freeMemory.stopTracker(); } } // Convert the data collected into arrays and use it to initialize the // stat trackers. int[] userArray = new int[userList.size()]; int[] systemArray = new int[systemList.size()]; int[] busyArray = new int[userList.size()]; int[] idleArray = new int[userList.size()]; int[] memArray = new int[freeMemoryList.size()]; int[] countArray = new int[userList.size()]; double[][] dataArray = new double[userList.size()][]; int peakUtilization = 0; int totalUtilization = 0; for (int i=0; i < userArray.length; i++) { userArray[i] = userList.get(i); systemArray[i] = systemList.get(i); idleArray[i] = 100 - userArray[i] - systemArray[i]; memArray[i] = freeMemoryList.get(i); busyArray[i] = userArray[i] + systemArray[i]; totalUtilization += busyArray[i]; if (busyArray[i] > peakUtilization) { peakUtilization = busyArray[i]; } dataArray[i] = new double[] { userArray[i], systemArray[i], idleArray[i] }; countArray[i] = 1; } if ((peakUtilization > 0) && (peakUtilizationLogThreshold > 0) && (peakUtilization > peakUtilizationLogThreshold)) { logMessage(getClientHostname() + " peak CPU utilization of " + peakUtilization + "% exceeds configured log threshold of " + peakUtilizationLogThreshold + '%'); } if (userArray.length > 0) { int averageUtilization = totalUtilization / userArray.length; if ((averageUtilization > 0) && (averageUtilizationLogThreshold > 0) && (averageUtilization > averageUtilizationLogThreshold)) { logMessage(getClientHostname() + " average CPU utilization of " + averageUtilization + "% exceeds configured log threshold " + "of " + averageUtilizationLogThreshold + '%'); } } cpuUserTime.setIntervalData(userArray, countArray); cpuSystemTime.setIntervalData(systemArray, countArray); cpuIdleTime.setIntervalData(idleArray, countArray); cpuBusyTime.setIntervalData(busyArray, countArray); cpuUtilization.setIntervalTotals(dataArray, countArray); freeMemory.setIntervalData(memArray, countArray); return stopReason; } /** * Parses the provided vmstat output line as generated from the Solaris vmstat * and extracts the CPU utilization from it. * * @param line The line of output generated by the Solaris vmstat. */ private void parseSolarisLine(String line) { if (line.startsWith(" procs") || line.startsWith(" r b w") || line.startsWith(" kthr") || line.startsWith("<<State change>>")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to capture // it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 4; i++) { tokenizer.nextToken(); } Integer freeMem = new Integer(tokenizer.nextToken()); freeMemoryList.add(freeMem); for (int i=0; i < 14; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(freeMem); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } /** * Parses the provided vmstat output line as generated from the Linux vmstat * (either the version from procps 2.x or procps 3.x) and extracts the CPU * utilization from it. * * @param line The line of output generated by the Linux vmstat. */ private void parseLinuxLine(String line) { if (linuxVMStatType == LINUX_VMSTAT_TYPE_PROCPS_2) { if (line.startsWith(" procs") || line.startsWith(" r b w")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to // capture it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 4; i++) { tokenizer.nextToken(); } int free = Integer.parseInt(tokenizer.nextToken()); int buff = Integer.parseInt(tokenizer.nextToken()); int cache = Integer.parseInt(tokenizer.nextToken()); freeMemoryList.add(free+buff+cache); for (int i=0; i < 6; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(free+buff+cache); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } else if ((linuxVMStatType == LINUX_VMSTAT_TYPE_PROCPS_3) || (linuxVMStatType == LINUX_VMSTAT_TYPE_RHEL_50)) { if (line.startsWith("procs -----") || line.startsWith(" r b")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to // capture it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 3; i++) { tokenizer.nextToken(); } int free = Integer.parseInt(tokenizer.nextToken()); int buff = Integer.parseInt(tokenizer.nextToken()); int cache = Integer.parseInt(tokenizer.nextToken()); freeMemoryList.add(free+buff+cache); for (int i=0; i < 6; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(free+buff+cache); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } else if (linuxVMStatType == LINUX_VMSTAT_TYPE_RHEL_30) { if (line.startsWith("procs") || line.startsWith(" r b")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to // capture it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 3; i++) { tokenizer.nextToken(); } int free = Integer.parseInt(tokenizer.nextToken()); int buff = Integer.parseInt(tokenizer.nextToken()); int cache = Integer.parseInt(tokenizer.nextToken()); freeMemoryList.add(free+buff+cache); for (int i=0; i < 6; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); Integer waitTime = new Integer(tokenizer.nextToken()); if (waitTime > 0) { systemTime = systemTime + waitTime; } if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(free+buff+cache); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } } /** * Parses the provided vmstat output line as generated from the HP-UX vmstat * and extracts the CPU utilization from it. * * @param line The line of output generated by the HP-UX vmstat. */ public void parseHPUXLine(String line) { if (line.startsWith(" procs") || line.startsWith(" r b")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to capture // it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 4; i++) { tokenizer.nextToken(); } Integer freeMem = new Integer(tokenizer.nextToken()); freeMemoryList.add(freeMem); for (int i=0; i < 10; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(freeMem); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } /** * Parses the provided vmstat output line as generated from the AIX vmstat * and extracts the CPU utilization from it. * * @param line The line of output generated by the AIX vmstat. */ public void parseAIXLine(String line) { if (line.startsWith("kthr") || line.startsWith("-----") || line.startsWith(" r b")) { // This is a header line and doesn't need to be parsed. return; } else if (skipFirstLine && (! firstLineSkipped)) { // This is a data line, but is the first one and we don't want to capture // it. firstLineSkipped = true; return; } else { try { StringTokenizer tokenizer = new StringTokenizer(line, " \t"); for (int i=0; i < 3; i++) { tokenizer.nextToken(); } Integer freeMem = new Integer(tokenizer.nextToken()); freeMemoryList.add(freeMem); for (int i=0; i < 9; i++) { tokenizer.nextToken(); } Integer userTime = new Integer(tokenizer.nextToken()); Integer systemTime = new Integer(tokenizer.nextToken()); Integer idleTime = new Integer(tokenizer.nextToken()); if (enableRealTimeStats) { if (captureCPUUser) { cpuUserTime.addValue(userTime); } if (captureCPUSystem) { cpuSystemTime.addValue(systemTime); } if (captureCPUIdle) { cpuIdleTime.addValue(idleTime); } if (captureCPUBusy) { cpuBusyTime.addValue(userTime + systemTime); } if (captureFreeMemory) { freeMemory.addValue(freeMem); } } userList.add(userTime); systemList.add(systemTime); } catch (Exception e) { logMessage("Unable to parse output line \"" + line + "\" -- " + e); } } } }