001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.web.tomcat.statistics;
023:
024: import java.io.Serializable;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: /** A web context invocation statistics collection class.
031: *
032: * @author Scott.Stark@jboss.org
033: * @version $Revision: 57206 $
034: */
035: public class InvocationStatistics implements Serializable {
036: /** The serial version ID */
037: private static final long serialVersionUID = 9153807780893455734L;
038:
039: /** A HashMap<String, TimeStatistic> of the method invocations */
040: private Map ctxStats;
041: /** The number of concurrent request across all contexts */
042: public volatile int concurrentCalls = 0;
043: /** The maximum number of concurrent request across all contexts */
044: public volatile int maxConcurrentCalls = 0;
045: /** Time of the last resetStats call */
046: public long lastResetTime = System.currentTimeMillis();
047:
048: public static class TimeStatistic {
049: public long count;
050: public long minTime = Long.MAX_VALUE;
051: public long maxTime;
052: public long totalTime;
053:
054: public void reset() {
055: count = 0;
056: minTime = Long.MAX_VALUE;
057: maxTime = 0;
058: totalTime = 0;
059: }
060: }
061:
062: public InvocationStatistics() {
063: ctxStats = Collections.synchronizedMap(new HashMap());
064: }
065:
066: /** Update the TimeStatistic for the given ctx. This does not synchronize
067: * on the TimeStatistic so the results are an approximate values.
068: *
069: * @param ctx the method to update the statistics for.
070: * @param elapsed the elapsed time in milliseconds for the invocation.
071: */
072: public void updateStats(String ctx, long elapsed) {
073: TimeStatistic stat = (TimeStatistic) ctxStats.get(ctx);
074: if (stat == null) {
075: stat = new TimeStatistic();
076: ctxStats.put(ctx, stat);
077: }
078: stat.count++;
079: stat.totalTime += elapsed;
080: if (stat.minTime > elapsed)
081: stat.minTime = elapsed;
082: if (stat.maxTime < elapsed)
083: stat.maxTime = elapsed;
084: }
085:
086: public void callIn() {
087: concurrentCalls++;
088: if (concurrentCalls > maxConcurrentCalls)
089: maxConcurrentCalls = concurrentCalls;
090: }
091:
092: public void callOut() {
093: concurrentCalls--;
094: }
095:
096: /** Resets all current TimeStatistics.
097: *
098: */
099: public void resetStats() {
100: synchronized (ctxStats) {
101: Iterator iter = ctxStats.values().iterator();
102: while (iter.hasNext()) {
103: TimeStatistic stat = (TimeStatistic) iter.next();
104: stat.reset();
105: }
106: }
107: maxConcurrentCalls = 0;
108: lastResetTime = System.currentTimeMillis();
109: }
110:
111: /** Access the current collection of ctx invocation statistics
112: *
113: * @return A HashMap<String, TimeStatistic> of the ctx invocations
114: */
115: public Map getStats() {
116: return ctxStats;
117: }
118:
119: public String toString() {
120: StringBuffer tmp = new StringBuffer("(concurrentCalls: ");
121: tmp.append(concurrentCalls);
122: tmp.append(", maxConcurrentCalls: ");
123: tmp.append(maxConcurrentCalls);
124:
125: HashMap copy = new HashMap(ctxStats);
126: Iterator iter = copy.entrySet().iterator();
127: while (iter.hasNext()) {
128: Map.Entry entry = (Map.Entry) iter.next();
129: TimeStatistic stat = (TimeStatistic) entry.getValue();
130: tmp.append("[webCtx: ");
131: tmp.append(entry.getKey());
132: tmp.append(", count=");
133: tmp.append(stat.count);
134: tmp.append(", minTime=");
135: tmp.append(stat.minTime);
136: tmp.append(", maxTime=");
137: tmp.append(stat.maxTime);
138: tmp.append(", totalTime=");
139: tmp.append(stat.totalTime);
140: tmp.append("];");
141: }
142: tmp.append(")");
143: return tmp.toString();
144: }
145:
146: /** Generate an XML fragement for the InvocationStatistics. The format is
147: * <InvocationStatistics concurrentCalls="c" maxConcurrentCalls="x">
148: * <webCtx name="ctx" count="x" minTime="y" maxTime="z" totalTime="t" />
149: * ...
150: * </InvocationStatistics>
151: *
152: * @return an XML representation of the InvocationStatistics
153: */
154: public String toXML() {
155: StringBuffer tmp = new StringBuffer(
156: "<InvocationStatistics concurrentCalls='");
157: tmp.append(concurrentCalls);
158: tmp.append("' maxConcurrentCalls='");
159: tmp.append(maxConcurrentCalls);
160: tmp.append("' >\n");
161:
162: HashMap copy = new HashMap(ctxStats);
163: Iterator iter = copy.entrySet().iterator();
164: while (iter.hasNext()) {
165: Map.Entry entry = (Map.Entry) iter.next();
166: TimeStatistic stat = (TimeStatistic) entry.getValue();
167: tmp.append("<webCtx name='");
168: tmp.append(entry.getKey());
169: tmp.append("' count='");
170: tmp.append(stat.count);
171: tmp.append("' minTime='");
172: tmp.append(stat.minTime);
173: tmp.append("' maxTime='");
174: tmp.append(stat.maxTime);
175: tmp.append("' totalTime='");
176: tmp.append(stat.totalTime);
177: tmp.append("' />\n");
178: }
179: tmp.append("</InvocationStatistics>");
180: return tmp.toString();
181: }
182: }
|