001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.base.util;
019:
020: import java.util.Map;
021: import java.util.HashMap;
022:
023: /**
024: * Timer handling utility
025: * Utility class for simple reporting of the progress of a process.
026: * Steps are labelled, and the time between each label (or message)
027: * and the time since the start are reported in each call to timerString.
028: *
029: */
030: public class UtilTimer {
031:
032: public static final String module = UtilTimer.class.getName();
033: protected static Map staticTimers = new HashMap();
034:
035: protected String timerName = null;
036: protected String lastMessage = null;
037:
038: protected long realStartTime;
039: protected long startTime;
040: protected long lastMessageTime;
041: protected boolean running = false;
042: protected boolean log = false;
043:
044: public static UtilTimer makeTimer() {
045: return new UtilTimer();
046: }
047:
048: /** Default constructor. Starts the timer. */
049: public UtilTimer() {
050: this ("", true);
051: }
052:
053: public UtilTimer(String timerName, boolean start) {
054: this (timerName, start, false);
055: }
056:
057: public UtilTimer(String timerName, boolean start, boolean log) {
058: this .timerName = timerName;
059: this .setLog(log);
060: if (start) {
061: this .startTimer();
062: }
063: }
064:
065: public void startTimer() {
066: this .lastMessageTime = realStartTime = startTime = System
067: .currentTimeMillis();
068: this .lastMessage = "Begin";
069: this .running = true;
070: }
071:
072: public String getName() {
073: return this .timerName;
074: }
075:
076: public boolean isRunning() {
077: return this .running;
078: }
079:
080: /** Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning
081: * @param message A message to put into the timer String
082: * @return A String with the timing information, the timer String
083: */
084: public String timerString(String message) {
085: return timerString(message, this .getClass().getName());
086: }
087:
088: /** Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning
089: * @param message A message to put into the timer String
090: * @param module The debug/log module/thread to use, can be null for root module
091: * @return A String with the timing information, the timer String
092: */
093: public String timerString(String message, String module) {
094: // time this call to avoid it interfering with the main timer
095: long tsStart = System.currentTimeMillis();
096:
097: String retString = "[[" + message + "- total:"
098: + secondsSinceStart();
099: if (lastMessage != null) {
100: retString += ",since last("
101: + ((lastMessage.length() > 20) ? (lastMessage
102: .substring(0, 17) + "...") : lastMessage)
103: + "):" + secondsSinceLast() + "]]";
104: } else {
105: retString += "]]";
106: }
107:
108: // append the timer name
109: if (UtilValidate.isNotEmpty(timerName)) {
110: retString = retString + " - '" + timerName + "'";
111: }
112:
113: lastMessage = message;
114: if (log)
115: Debug.log(Debug.TIMING, null, retString, module,
116: "org.ofbiz.base.util.UtilTimer");
117:
118: // have lastMessageTime come as late as possible to just time what happens between calls
119: lastMessageTime = System.currentTimeMillis();
120: // update startTime to disclude the time this call took
121: startTime += (lastMessageTime - tsStart);
122:
123: return retString;
124: }
125:
126: /** Returns the number of seconds since the timer started
127: * @return The number of seconds since the timer started
128: */
129: public double secondsSinceStart() {
130: return ((double) timeSinceStart()) / 1000.0;
131: }
132:
133: /** Returns the number of seconds since the last time timerString was called
134: * @return The number of seconds since the last time timerString was called
135: */
136: public double secondsSinceLast() {
137: return ((double) timeSinceLast()) / 1000.0;
138: }
139:
140: /** Returns the number of milliseconds since the timer started
141: * @return The number of milliseconds since the timer started
142: */
143: public long timeSinceStart() {
144: long currentTime = System.currentTimeMillis();
145:
146: return currentTime - startTime;
147: }
148:
149: /** Returns the number of milliseconds since the last time timerString was called
150: * @return The number of milliseconds since the last time timerString was called
151: */
152: public long timeSinceLast() {
153: long currentTime = System.currentTimeMillis();
154:
155: return currentTime - lastMessageTime;
156: }
157:
158: /** Sets the value of the log member, denoting whether log output is off or not
159: * @param log The new value of log
160: */
161: public void setLog(boolean log) {
162: this .log = log;
163: }
164:
165: /** Gets the value of the log member, denoting whether log output is off or not
166: * @return The value of log
167: */
168: public boolean getLog() {
169: return log;
170: }
171:
172: /** Creates a string with information including the passed message, the time since the last call,
173: * and the time since the beginning. This version allows an integer level to be specified to
174: * improve readability of the output.
175: * @param level Integer specifying how many levels to indent the timer string so the output can be more easily read through nested method calls.
176: * @param message A message to put into the timer String
177: * @return A String with the timing information, the timer String
178: */
179: public String timerString(int level, String message) {
180: // String retString = "[[" + message + ": seconds since start: " + secondsSinceStart() + ",since last(" + lastMessage + "):" + secondsSinceLast() + "]]";
181:
182: StringBuffer retStringBuf = new StringBuffer();
183:
184: for (int i = 0; i < level; i++) {
185: retStringBuf.append("| ");
186: }
187: retStringBuf.append("(");
188:
189: String timeSinceStartStr = String.valueOf(timeSinceStart());
190:
191: // int spacecount = 5 - timeSinceStartStr.length();
192: // for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); }
193: retStringBuf.append(timeSinceStartStr + ",");
194:
195: String timeSinceLastStr = String.valueOf(timeSinceLast());
196:
197: // spacecount = 4 - timeSinceLastStr.length();
198: // for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); }
199: retStringBuf.append(timeSinceLastStr);
200:
201: retStringBuf.append(")");
202: int spacecount = 12 + (2 * level) - retStringBuf.length();
203:
204: for (int i = 0; i < spacecount; i++) {
205: retStringBuf.append(' ');
206: }
207: retStringBuf.append(message);
208:
209: // lastMessageTime = (new Date()).getTime();
210: lastMessageTime = System.currentTimeMillis();
211: // lastMessage = message;
212:
213: String retString = retStringBuf.toString();
214:
215: // if(!quiet) Debug.logInfo(retString, module);
216: if (log && Debug.timingOn())
217: Debug.logTiming(retString, module);
218: return retString;
219: }
220:
221: // static logging timer - be sure to close the timer when finished!
222:
223: public static UtilTimer getTimer(String timerName) {
224: return getTimer(timerName, true);
225: }
226:
227: public static UtilTimer getTimer(String timerName, boolean log) {
228: UtilTimer timer = (UtilTimer) staticTimers.get(timerName);
229: if (timer == null) {
230: synchronized (UtilTimer.class) {
231: timer = (UtilTimer) staticTimers.get(timerName);
232: if (timer == null) {
233: timer = new UtilTimer(timerName, false);
234: timer.setLog(log);
235: staticTimers.put(timerName, timer);
236: }
237: }
238: }
239: return timer;
240: }
241:
242: public static void timerLog(String timerName, String message,
243: String module) {
244: UtilTimer timer = UtilTimer.getTimer(timerName);
245: if (!timer.isRunning()) {
246: timer.startTimer();
247: }
248:
249: if (timer.getLog()) {
250: if (module == null) {
251: module = timer.getClass().getName();
252: }
253: timer.timerString(message, module);
254: }
255: }
256:
257: public static void closeTimer(String timerName) {
258: UtilTimer.closeTimer(timerName, null, null);
259: }
260:
261: public static void closeTimer(String timerName, String message) {
262: UtilTimer.closeTimer(timerName, message, null);
263: }
264:
265: public static void closeTimer(String timerName, String message,
266: String module) {
267: if (message != null) {
268: UtilTimer.timerLog(timerName, message, module);
269: }
270: synchronized (UtilTimer.class) {
271: staticTimers.remove(timerName);
272: }
273: }
274: }
|