001: //========================================================================
002: //Copyright 2006 Mort Bay Consulting Pty. Ltd.
003: //------------------------------------------------------------------------
004: //Licensed under the Apache License, Version 2.0 (the "License");
005: //you may not use this file except in compliance with the License.
006: //You may obtain a copy of the License at
007: //http://www.apache.org/licenses/LICENSE-2.0
008: //Unless required by applicable law or agreed to in writing, software
009: //distributed under the License is distributed on an "AS IS" BASIS,
010: //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: //See the License for the specific language governing permissions and
012: //limitations under the License.
013: //========================================================================
014:
015: package org.mortbay.jetty.handler;
016:
017: import java.io.IOException;
018:
019: import javax.servlet.ServletException;
020: import javax.servlet.http.HttpServletRequest;
021: import javax.servlet.http.HttpServletResponse;
022:
023: import org.mortbay.jetty.HttpConnection;
024: import org.mortbay.jetty.Request;
025: import org.mortbay.jetty.Response;
026:
027: public class StatisticsHandler extends HandlerWrapper {
028: transient long _statsStartedAt;
029:
030: transient int _requests;
031:
032: transient long _requestsDurationMin; // min request duration
033: transient long _requestsDurationMax; // max request duration
034: transient long _requestsDurationTotal; // total request duration
035:
036: transient int _requestsActive;
037: transient int _requestsActiveMin; // min number of connections handled simultaneously
038: transient int _requestsActiveMax;
039: transient int _responses1xx; // Informal
040: transient int _responses2xx; // Success
041: transient int _responses3xx; // Redirection
042: transient int _responses4xx; // Client Error
043: transient int _responses5xx; // Server Error
044:
045: /* ------------------------------------------------------------ */
046: public void statsReset() {
047: synchronized (this ) {
048: if (isStarted())
049: _statsStartedAt = System.currentTimeMillis();
050: _requests = 0;
051: _requestsActiveMax = _requestsActive;
052: _responses1xx = 0;
053: _responses2xx = 0;
054: _responses3xx = 0;
055: _responses4xx = 0;
056: _responses5xx = 0;
057:
058: _requestsActiveMin = _requestsActive;
059: _requestsActiveMax = _requestsActive;
060: _requestsActive = 0;
061:
062: _requestsDurationMin = 0;
063: _requestsDurationMax = 0;
064: _requestsDurationTotal = 0;
065: }
066: }
067:
068: /* ------------------------------------------------------------ */
069: public void handle(String target, HttpServletRequest request,
070: HttpServletResponse response, int dispatch)
071: throws IOException, ServletException {
072: final Request base_request = (request instanceof Request) ? ((Request) request)
073: : HttpConnection.getCurrentConnection().getRequest();
074: final Response base_response = (response instanceof Response) ? ((Response) response)
075: : HttpConnection.getCurrentConnection().getResponse();
076:
077: try {
078: synchronized (this ) {
079: _requests++;
080: _requestsActive++;
081: if (_requestsActive > _requestsActiveMax)
082: _requestsActiveMax = _requestsActive;
083: }
084:
085: super .handle(target, request, response, dispatch);
086: } finally {
087: synchronized (this ) {
088: _requestsActive--;
089: if (_requestsActive < 0)
090: _requestsActive = 0;
091: if (_requestsActive < _requestsActiveMin)
092: _requestsActiveMin = _requestsActive;
093:
094: long duration = System.currentTimeMillis()
095: - base_request.getTimeStamp();
096:
097: _requestsDurationTotal += duration;
098: if (_requestsDurationMin == 0
099: || duration < _requestsDurationMin)
100: _requestsDurationMin = duration;
101: if (duration > _requestsDurationMax)
102: _requestsDurationMax = duration;
103:
104: switch (base_response.getStatus() / 100) {
105: case 1:
106: _responses1xx++;
107: break;
108: case 2:
109: _responses2xx++;
110: break;
111: case 3:
112: _responses3xx++;
113: break;
114: case 4:
115: _responses4xx++;
116: break;
117: case 5:
118: _responses5xx++;
119: break;
120: }
121:
122: }
123: }
124: }
125:
126: /* ------------------------------------------------------------ */
127: protected void doStart() throws Exception {
128: super .doStart();
129: _statsStartedAt = System.currentTimeMillis();
130: }
131:
132: /* ------------------------------------------------------------ */
133: protected void doStop() throws Exception {
134: super .doStop();
135: }
136:
137: /* ------------------------------------------------------------ */
138: /**
139: * @return Get the number of requests handled by this context
140: * since last call of statsReset(). If setStatsOn(false) then this
141: * is undefined.
142: */
143: public int getRequests() {
144: return _requests;
145: }
146:
147: /* ------------------------------------------------------------ */
148: /**
149: * @return Number of requests currently active.
150: * Undefined if setStatsOn(false).
151: */
152: public int getRequestsActive() {
153: return _requestsActive;
154: }
155:
156: /* ------------------------------------------------------------ */
157: /**
158: * @return Maximum number of active requests
159: * since statsReset() called. Undefined if setStatsOn(false).
160: */
161: public int getRequestsActiveMax() {
162: return _requestsActiveMax;
163: }
164:
165: /* ------------------------------------------------------------ */
166: /**
167: * @return Get the number of responses with a 2xx status returned
168: * by this context since last call of statsReset(). Undefined if
169: * if setStatsOn(false).
170: */
171: public int getResponses1xx() {
172: return _responses1xx;
173: }
174:
175: /* ------------------------------------------------------------ */
176: /**
177: * @return Get the number of responses with a 100 status returned
178: * by this context since last call of statsReset(). Undefined if
179: * if setStatsOn(false).
180: */
181: public int getResponses2xx() {
182: return _responses2xx;
183: }
184:
185: /* ------------------------------------------------------------ */
186: /**
187: * @return Get the number of responses with a 3xx status returned
188: * by this context since last call of statsReset(). Undefined if
189: * if setStatsOn(false).
190: */
191: public int getResponses3xx() {
192: return _responses3xx;
193: }
194:
195: /* ------------------------------------------------------------ */
196: /**
197: * @return Get the number of responses with a 4xx status returned
198: * by this context since last call of statsReset(). Undefined if
199: * if setStatsOn(false).
200: */
201: public int getResponses4xx() {
202: return _responses4xx;
203: }
204:
205: /* ------------------------------------------------------------ */
206: /**
207: * @return Get the number of responses with a 5xx status returned
208: * by this context since last call of statsReset(). Undefined if
209: * if setStatsOn(false).
210: */
211: public int getResponses5xx() {
212: return _responses5xx;
213: }
214:
215: /* ------------------------------------------------------------ */
216: /**
217: * @return Timestamp stats were started at.
218: */
219: public long getStatsOnMs() {
220: return System.currentTimeMillis() - _statsStartedAt;
221: }
222:
223: /* ------------------------------------------------------------ */
224: /**
225: * @return Returns the requestsActiveMin.
226: */
227: public int getRequestsActiveMin() {
228: return _requestsActiveMin;
229: }
230:
231: /* ------------------------------------------------------------ */
232: /**
233: * @return Returns the requestsDurationMin.
234: */
235: public long getRequestsDurationMin() {
236: return _requestsDurationMin;
237: }
238:
239: /* ------------------------------------------------------------ */
240: /**
241: * @return Returns the requestsDurationTotal.
242: */
243: public long getRequestsDurationTotal() {
244: return _requestsDurationTotal;
245: }
246:
247: /* ------------------------------------------------------------ */
248: /**
249: * @return Average duration of request handling in milliseconds
250: * since statsReset() called. Undefined if setStatsOn(false).
251: */
252: public long getRequestsDurationAve() {
253: return _requests == 0 ? 0
254: : (_requestsDurationTotal / _requests);
255: }
256:
257: /* ------------------------------------------------------------ */
258: /**
259: * @return Get maximum duration in milliseconds of request handling
260: * since statsReset() called. Undefined if setStatsOn(false).
261: */
262: public long getRequestsDurationMax() {
263: return _requestsDurationMax;
264: }
265:
266: }
|