001: package org.incava.qualog;
002:
003: import java.util.*;
004:
005: public class QlTimer {
006: private List periods = null;
007:
008: public QlTimer() {
009: periods = new ArrayList();
010: }
011:
012: public boolean start() {
013: return start(null);
014: }
015:
016: public boolean end() {
017: return end(null);
018: }
019:
020: public boolean start(String msg) {
021: StackTraceElement ste = getFrame();
022:
023: String className = ste.getClassName();
024: String methodName = ste.getMethodName();
025: int lineNumber = ste.getLineNumber();
026: String fileName = ste.getFileName();
027:
028: QlTimedPeriod qtp = new QlTimedPeriod(fileName, className,
029: methodName, lineNumber, msg);
030: periods.add(qtp);
031:
032: return true;
033: }
034:
035: public boolean end(String msg) {
036: long endTime = System.currentTimeMillis();
037:
038: StackTraceElement ste = getFrame();
039:
040: // System.out.println("ste: " + ste);
041:
042: String className = ste.getClassName();
043: String methodName = ste.getMethodName();
044: int lineNumber = ste.getLineNumber();
045: String fileName = ste.getFileName();
046: int bestMatchIdx = -1;
047: int bestMatchness = -1;
048:
049: Iterator it = periods.iterator();
050: for (int idx = 0; it.hasNext(); ++idx) {
051: Object obj = it.next();
052: QlTimedPeriod qtp = (QlTimedPeriod) obj;
053: int matchness = 0;
054:
055: matchness += qtp.getMessage() != null
056: && msg.equals(qtp.getMessage()) ? 1 : 0;
057: matchness += className.equals(qtp.getClassName()) ? 1 : 0;
058: matchness += fileName.equals(qtp.getFileName()) ? 1 : 0;
059: matchness += methodName.equals(qtp.getMethodName()) ? 1 : 0;
060:
061: // System.out.println("matchness: " + matchness);
062: if (matchness >= bestMatchness) {
063: bestMatchness = matchness;
064: bestMatchIdx = idx;
065: }
066: }
067:
068: // System.out.println("best matchness: " + bestMatchness);
069: // System.out.println("best match idx: " + bestMatchIdx);
070:
071: if (bestMatchIdx >= 0) {
072: QlTimedPeriod qtp = (QlTimedPeriod) periods
073: .remove(bestMatchIdx);
074: long elapsed = endTime - qtp.getStartTime();
075: StringBuffer buf = new StringBuffer();
076:
077: buf.append(format(elapsed));
078: buf.append("; ");
079:
080: if (msg != null) {
081: buf.append(msg);
082: buf.append("; ");
083: }
084:
085: buf.append("from: [");
086: buf.append(fileName);
087: buf.append(":");
088: buf.append(Integer.toString(lineNumber));
089: buf.append("]");
090: buf.append(" ");
091:
092: buf.append("{");
093: buf.append(className);
094: buf.append("#");
095: buf.append(methodName);
096: buf.append("}");
097:
098: Qualog.log(buf.toString());
099: } else {
100: System.err.println("ERROR no matching start!");
101: }
102:
103: return true;
104: }
105:
106: protected StackTraceElement getFrame() {
107: StackTraceElement[] stack = (new Exception("")).getStackTrace();
108: int stIdx = Qualog.findStackStart(stack);
109: StackTraceElement ste = stack[stIdx];
110:
111: return ste;
112: }
113:
114: public String format(long duration) {
115: StringBuffer buf = new StringBuffer();
116: if (duration < 10000) {
117: buf.append(Long.toString(duration));
118: buf.append(" ms");
119: } else if (duration < 100000) {
120: double nSecs = duration / 1000.0;
121: buf.append(Double.toString(nSecs));
122: buf.append(" sec");
123: } else if (duration < 1000000) {
124: double nMin = Math.floor(duration / (60 * 1000.0));
125: double nSec = (duration - 60.0 * nMin) / 1000.0;
126: buf.append(Double.toString(nMin));
127: buf.append(":");
128: buf.append(Double.toString(nSec));
129: } else {
130: // convert to HH:MM:SS, etc.
131: buf.append(Long.toString(duration));
132: }
133: return buf.toString();
134: }
135:
136: }
|