001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2007 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.qos.qrs.sysstat;
028:
029: import org.cougaar.qos.qrs.DataValue;
030: import org.cougaar.qos.qrs.Logging;
031: import org.cougaar.util.log.Logger;
032:
033: import java.io.InputStream;
034: import java.io.InputStreamReader;
035: import java.io.BufferedReader;
036: import java.util.Map;
037: import java.util.StringTokenizer;
038:
039: public class ProcessStats extends SysStatHandler {
040: private static final String CommandPrefix = "/bin/ps -o pcpu,pmem,rss,time -p ";
041:
042: private String cpu_key, mem_key, rsz_key, cputime_key;
043: private String command;
044:
045: public static String makePCPUKey(String host, int pid) {
046: return "Host" + KEY_SEPR + host + KEY_SEPR + "Process"
047: + KEY_SEPR + pid + KEY_SEPR + "%CPU";
048: }
049:
050: public static String makePMEMKey(String host, int pid) {
051: return "Host" + KEY_SEPR + host + KEY_SEPR + "Process"
052: + KEY_SEPR + pid + KEY_SEPR + "%MEM";
053: }
054:
055: public static String makeRSZKey(String host, int pid) {
056: return "Host" + KEY_SEPR + host + KEY_SEPR + "Process"
057: + KEY_SEPR + pid + KEY_SEPR + "RSZ";
058: }
059:
060: public static String makeCPUTIMEKey(String host, int pid) {
061: return "Host" + KEY_SEPR + host + KEY_SEPR + "Process"
062: + KEY_SEPR + pid + KEY_SEPR + "CPUTIME";
063: }
064:
065: public void initialize(String host, int pid) {
066: cpu_key = makePCPUKey(host, pid);
067: mem_key = makePMEMKey(host, pid);
068: rsz_key = makeRSZKey(host, pid);
069: cputime_key = makeCPUTIMEKey(host, pid);
070: command = CommandPrefix + pid;
071: }
072:
073: // Units = hundredths of a second
074: private static final int UNITS_PER_SEC = 100;
075: private static final int UNITS_PER_MIN = UNITS_PER_SEC * 60;
076: private static final int UNITS_PER_HOUR = UNITS_PER_MIN * 60;
077: private static final int UNITS_PER_DAY = UNITS_PER_HOUR * 24;
078:
079: private int parseTime(String cput) {
080: // [[days-]hour:]minutes:seconds[.hundredths-of-a-second]
081: int core_start = 0;
082: int core_end = cput.length();
083:
084: int dash = cput.indexOf('-');
085: int result = 0;
086: if (dash > 0) {
087: String days = cput.substring(0, dash);
088: result = Integer.parseInt(days) * UNITS_PER_DAY;
089: core_start = dash + 1;
090: }
091:
092: int dot = cput.indexOf('.');
093: if (dot > 0) {
094: String hsecs = cput.substring(dot + 1);
095: result += Integer.parseInt(hsecs);
096: core_end = dot;
097: }
098:
099: int hours = 0;
100: int minutes = 0;
101: int seconds = 0;
102:
103: String core = cput.substring(core_start, core_end);
104: StringTokenizer tk = new StringTokenizer(core, ":");
105: int tokens = tk.countTokens();
106: switch (tokens) {
107: case 1:
108: seconds = Integer.parseInt(tk.nextToken());
109: break;
110:
111: case 2:
112: minutes = Integer.parseInt(tk.nextToken());
113: seconds = Integer.parseInt(tk.nextToken());
114: break;
115:
116: case 3:
117: hours = Integer.parseInt(tk.nextToken());
118: minutes = Integer.parseInt(tk.nextToken());
119: seconds = Integer.parseInt(tk.nextToken());
120: break;
121: }
122:
123: result += hours * UNITS_PER_HOUR + minutes * UNITS_PER_MIN
124: + seconds * UNITS_PER_SEC;
125:
126: return result;
127:
128: }
129:
130: public void getData(Map<String, DataValue> map) {
131: Logger logger = Logging.getLogger(ProcessStats.class);
132: String line = null;
133: try {
134: Process process = Runtime.getRuntime().exec(command);
135: InputStream stdOut = process.getInputStream();
136: InputStreamReader rdr = new InputStreamReader(stdOut);
137: BufferedReader bufferedStdOut = new BufferedReader(rdr);
138: line = bufferedStdOut.readLine(); // ignore this one
139: line = bufferedStdOut.readLine();
140: bufferedStdOut.close();
141: process.destroy();
142: } catch (java.io.IOException ioex) {
143: logger.warn("Error running ps: " + ioex.getMessage());
144: return;
145: }
146:
147: if (line != null) {
148: StringTokenizer tk = new StringTokenizer(line, " ");
149: String pcpu = tk.nextToken();
150: String pmem = tk.nextToken();
151: String rsz = tk.nextToken();
152: String cput = tk.nextToken();
153: double percent_cpu = Double.parseDouble(pcpu);
154: double percent_mem = Double.parseDouble(pmem);
155: int res_size = Integer.parseInt(rsz);
156: int cpu_time = parseTime(cput);
157: map.put(cpu_key, new DataValue(percent_cpu,
158: SECOND_MEAS_CREDIBILITY, "", PROVENANCE));
159: map.put(mem_key, new DataValue(percent_mem,
160: SECOND_MEAS_CREDIBILITY, "", PROVENANCE));
161: map.put(rsz_key, new DataValue(res_size,
162: SECOND_MEAS_CREDIBILITY, "KB", PROVENANCE));
163: map.put(cputime_key, new DataValue(cpu_time,
164: SECOND_MEAS_CREDIBILITY, "KB", PROVENANCE));
165: }
166: }
167:
168: }
|