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 persistence activity for each
021: * agent and the aggegate node "sum".
022: * <p>
023: * Persistence must be enabled with<br>
024: * -Dorg.cougaar.core.persistence.enable=true<br>
025: * otherwise this profiler does nothing.
026: * <p>
027: * Example output:<pre>
028: * pdir_AgentA - #sumActive, mostRecent, sumAll, timestamp,
029: * time_delta, max, first, last, numFiles,
030: * pdir_AgentA - 11461496, 2809731, 11461531, 1103647670000,
031: * 7143025, 3286631, 0, 5, 8,
032: * psum_NodeA - #sumActive, sumAll
033: * psum_NodeA - 63742420, 63742665
034: * <pre>
035: *
036: * @see ProfilerCoordinator required coordinator component
037: * @see org.cougaar.core.qos.metrics.PersistenceAdapterPlugin
038: * required per-agent component
039: */
040: public class PersistSize extends ProfilerBase {
041: private static final DecimalFormat INT_FORMAT = new DecimalFormat(
042: "########0");
043: private static final DecimalFormat LONG_FORMAT = new DecimalFormat(
044: "################0");
045: private static final DecimalFormat DELTA_FORMAT = new DecimalFormat(
046: "_00000");
047: private boolean enabled;
048: private MessageAddress nodeId;
049: private AgentContainer ac;
050: private String baseDir;
051: private final Map logs = new HashMap();
052:
053: public void load() {
054: super .load();
055:
056: enabled = "true".equals(System
057: .getProperty("org.cougaar.core.persistence.enable"));
058: if (!enabled) {
059: return;
060: }
061:
062: NodeIdentificationService nis = (NodeIdentificationService) sb
063: .getService(this , NodeIdentificationService.class, null);
064: nodeId = nis.getMessageAddress();
065: sb.releaseService(this , NodeIdentificationService.class, nis);
066:
067: NodeControlService ncs = (NodeControlService) sb.getService(
068: this , NodeControlService.class, null);
069: ac = ncs.getRootContainer();
070: sb.releaseService(this , NodeControlService.class, ncs);
071:
072: String installPath = System.getProperty(
073: "org.cougaar.install.path", "/tmp");
074: String workspaceDir = System.getProperty(
075: "org.cougaar.workspace", installPath + "/workspace");
076: baseDir = workspaceDir + "/P";
077: }
078:
079: public void run() {
080: if (enabled) {
081: logP();
082: }
083: }
084:
085: private void logP() {
086: long sumActive = 0;
087: long sumAll = 0;
088: Set agents = ac.getAgentAddresses();
089: for (Iterator iter = agents.iterator(); iter.hasNext();) {
090: String agent = ((MessageAddress) iter.next()).getAddress();
091: PersistenceData p = readP(agent);
092: if (p == null) {
093: continue;
094: }
095: sumActive += p.sumActive;
096: sumAll += p.sumAll;
097: getLog("pdir_" + agent).shout(p.toString());
098: }
099: getLog("psum_" + nodeId).shout(
100: formatLong(sumActive) + ", " + formatLong(sumAll));
101: }
102:
103: private String formatLong(long l) {
104: return LONG_FORMAT.format(l);
105: }
106:
107: private PersistenceData readP(String agent) {
108: String dir = baseDir + "/" + agent;
109: File f = new File(dir);
110: if (!f.isDirectory()) {
111: return null;
112: }
113: PersistenceData p = new PersistenceData();
114: // read sequence numbers
115: File sequenceFile = new File(dir, "sequence");
116: if (sequenceFile.exists()) {
117: try {
118: DataInputStream sequenceStream = new DataInputStream(
119: new BufferedInputStream(new FileInputStream(
120: sequenceFile)));
121: p.first = sequenceStream.readInt();
122: p.last = sequenceStream.readInt();
123: p.timestamp = sequenceFile.lastModified();
124: sequenceStream.close();
125: // most recent delta
126: p.mostRecent = getDeltaFile(dir, p.last - 1).length();
127: // total for rehydrate
128: for (int i = p.first; i < p.last; i++) {
129: p.sumActive += getDeltaFile(dir, i).length();
130: }
131: } catch (Exception e) {
132: }
133: }
134: // sum disk usage (includes ancient deltas)
135: File[] fa = f.listFiles();
136: p.numFiles = fa.length;
137: for (int i = 0; i < fa.length; i++) {
138: long len = fa[i].length();
139: if (len > p.max) {
140: p.max = len;
141: }
142: p.sumAll += len;
143: }
144: return p;
145: }
146:
147: private LoggingService getLog(String key) {
148: key = key.replace('.', '_');
149: LoggingService log;
150: synchronized (logs) {
151: log = (LoggingService) logs.get(key);
152: if (log == null) {
153: log = (LoggingService) sb.getService(
154: "org.cougaar.core.qos.profile.persistence."
155: + key, LoggingService.class, null);
156: logs.put(key, log);
157: log.shout(getHeader(key));
158: if (align) {
159: String s = getAlign(key);
160: for (int i = 0, n = getRunCount(); i < n; i++) {
161: log.shout(s);
162: }
163: }
164: }
165: }
166: return log;
167: }
168:
169: private String getHeader(String key) {
170: return (key.startsWith("psum") ? "#" + "sumActive, " + "sumAll"
171: : PersistenceData.HEADER);
172: }
173:
174: private String getAlign(String key) {
175: return (key.startsWith("psum") ? "0, 0" : PersistenceData.ALIGN);
176: }
177:
178: private File getDeltaFile(String dir, int num) {
179: return new File(dir, "delta" + DELTA_FORMAT.format(num));
180: }
181:
182: private static final class PersistenceData {
183: public static final String HEADER = "#" + "sumActive, "
184: + "mostRecent, " + "sumAll, " + "timestamp, "
185: + "time_delta, " + "max, " + "first, " + "last, "
186: + "numFiles, ";
187: public static final String ALIGN = "0, " + "0, " + "0, "
188: + "0, " + // timestamp?
189: "0, " + "0, " + "0, " + "0, " + "0, ";
190: public long sumActive;
191: public long mostRecent;
192: public long sumAll;
193: public long timestamp;
194: public long max;
195: public int first;
196: public int last;
197: public int numFiles;
198:
199: public String toString() {
200: long now = System.currentTimeMillis();
201: // 0, 0, 8588, 1103326510000, 14395, 8553, 0, 1, 0,
202: return formatLong(sumActive) + ", "
203: + formatLong(mostRecent) + ", "
204: + formatLong(sumAll) + ", " + formatLong(timestamp)
205: + ", "
206: + formatLong(timestamp > 0 ? now - timestamp : 0)
207: + ", " + formatLong(max) + ", " + formatInt(first)
208: + ", " + formatInt(last) + ", "
209: + formatInt(numFiles) + ", ";
210: }
211:
212: private String formatInt(int i) {
213: return INT_FORMAT.format(i);
214: }
215:
216: private String formatLong(long l) {
217: return LONG_FORMAT.format(l);
218: }
219: }
220: }
|