001: package org.cougaar.core.qos.profile;
002:
003: import java.lang.reflect.*;
004: import java.io.*;
005: import java.text.*;
006: import java.util.*;
007: import java.util.regex.*;
008: import org.cougaar.core.agent.*;
009: import org.cougaar.core.component.*;
010: import org.cougaar.core.mts.*;
011: import org.cougaar.core.node.*;
012: import org.cougaar.core.qos.metrics.*;
013: import org.cougaar.core.service.*;
014: import org.cougaar.core.service.wp.*;
015: import org.cougaar.core.thread.*;
016: import org.cougaar.core.wp.resolver.*;
017: import org.cougaar.util.*;
018:
019: /**
020: * This component profiles system activity from "/proc/stat".
021: *
022: * @see ProfilerCoordinator required coordinator component
023: */
024: public class ProcStat extends ProfilerBase {
025: //From periodic "cat /proc/stat", example output:
026: // cpu 1800570 485 1156647 295121622
027: // cpu0 939814 240 583264 147516343
028: // cpu1 860756 245 573383 147605278
029: // page 128169 13690722
030: // swap 1 0
031: // intr 778253440 763083074 ..
032: // disk_io: (8,0):(606661,3534,47026,603127,16947752) (8,1):(652067,12102,208134,639965,10433680)
033: // ctxt 35696933
034: // btime 1103025654
035: // processes 586574
036: private/*static*/final String[][] FIELDS = new String[][] {
037: { "cpu", "user_100th_sec", "nice_100th_sec",
038: "system_100th_sec", "idle_100th_sec", },
039: { "page", "pages_in", "pages_out", },
040: { "intr", "num_interrupts", "etc", },
041: { "swap", "pages_in", "pages_out", },
042: { "disk_io", "id_major", "id_minor", "total_ops",
043: "read_io_ops", "read_blocks", "write_io_ops",
044: "write_blocks", }, { "ctxt", "context_switches", },
045: { "btime", "boot_time_since_1970_sec", },
046: { "processes", "fork_counter", }, };
047: private/*static*/final Map HEADERS = initHeaders();
048:
049: private Map initHeaders() /*static */{
050: Map m = new HashMap();
051: for (int i = 0; i < FIELDS.length; i++) {
052: String[] sa = FIELDS[i];
053: StringBuffer buf = new StringBuffer();
054: buf.append("#");
055: for (int j = 1; j < sa.length; j++) {
056: buf.append(sa[j]).append(", ");
057: }
058: m.put(sa[0], buf.toString());
059: }
060: return m;
061: }
062:
063: private Map logs = new HashMap();
064:
065: public void run() {
066: logStat();
067: }
068:
069: private void logStat() {
070: // The "cpu" numbers are (from the "proc" man page):
071: // The number of jiffies (1/100ths of a second) that the
072: // system spent in user mode, user mode with low priority
073: // (nice), system mode, and the idle task, respectively
074: // "disc_io" fields are (from the "proc" man page):
075: // (major,minor):(noinfo, read_io_ops, blks_read,
076: // write_io_ops, blks_written)
077: // where "noinfo" is "read_io_ops + write_io_ops
078: StringBuffer buf = new StringBuffer();
079: try {
080: BufferedReader in = new BufferedReader(new FileReader(
081: "/proc/stat"));
082: while (true) {
083: String line = in.readLine();
084: if (line == null) {
085: break;
086: }
087: int sep = line.indexOf(' ');
088: String key = line.substring(0, sep);
089: if (key.equals("intr")) {
090: continue;
091: }
092: String value = line.substring(sep + 1);
093: if (key.equals("disk_io:")) {
094: key = "disk_io";
095: if (value.indexOf(" (") < 0) {
096: recordDiskIO(value);
097: } else {
098: String[] sa = value.trim().split(" \\(");
099: for (int i = 0; i < sa.length; i++) {
100: recordDiskIO(sa[i]);
101: }
102: }
103: continue;
104: }
105: record(key, value);
106: }
107: } catch (Exception e) {
108: }
109: }
110:
111: private void recordDiskIO(String value) {
112: // (8,0):(606661,3534,47026,603127,16947752)
113: String s = value.replace('(', ' ').replace(',', ' ').replace(
114: ':', ' ').replace(')', ' ').trim();
115: String[] sa = s.split("\\s+");
116: String key = "disk_io_" + sa[0] + "_" + sa[1];
117: record(key, s);
118: }
119:
120: private void record(String key, String value) {
121: StringBuffer buf = new StringBuffer();
122: String[] sa = value.trim().split("\\s+");
123: for (int i = 0; i < sa.length; i++) {
124: for (int j = 8 - sa[i].length(); j > 0; j--) {
125: buf.append(" ");
126: }
127: buf.append(sa[i]).append(", ");
128: }
129: String s = buf.toString();
130: log(key, s);
131: }
132:
133: private void log(String key, String value) {
134: LoggingService log;
135: synchronized (logs) {
136: log = (LoggingService) logs.get(key);
137: if (log == null) {
138: log = (LoggingService) sb
139: .getService(
140: "org.cougaar.core.qos.profile.proc.stat."
141: + key, LoggingService.class,
142: null);
143: logs.put(key, log);
144: if (header) {
145: log.shout(getHeader(key));
146: }
147: if (align) {
148: // ALIGN as current value
149: for (int i = 0, n = getRunCount(); i < n; i++) {
150: log.shout(value);
151: }
152: }
153: }
154: }
155: log.shout(value);
156: }
157:
158: private String getHeader(String key) {
159: String s = (String) HEADERS.get(key);
160: if (s != null) {
161: return s;
162: }
163: if (key.startsWith("cpu")) {
164: return (String) HEADERS.get("cpu");
165: }
166: if (key.startsWith("disk_io")) {
167: return (String) HEADERS.get("disk_io");
168: }
169: return "unknown";
170: }
171: }
|