1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.handler;
15
16 import java.io.IOException;
17 import java.util.concurrent.atomic.AtomicInteger;
18 import java.util.concurrent.atomic.AtomicLong;
19 import javax.servlet.ServletException;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.eclipse.jetty.server.AsyncContinuation;
24 import org.eclipse.jetty.server.Request;
25 import org.eclipse.jetty.server.Response;
26
27 public class StatisticsHandler extends HandlerWrapper
28 {
29 private transient final AtomicLong _statsStartedAt = new AtomicLong();
30 private transient final AtomicInteger _requests = new AtomicInteger();
31 private transient final AtomicInteger _resumedRequests = new AtomicInteger();
32 private transient final AtomicInteger _expiredRequests = new AtomicInteger();
33 private transient final AtomicLong _requestMinTime = new AtomicLong();
34 private transient final AtomicLong _requestMaxTime = new AtomicLong();
35 private transient final AtomicLong _requestTotalTime = new AtomicLong();
36 private transient final AtomicLong _suspendMinTime = new AtomicLong();
37 private transient final AtomicLong _suspendTotalTime = new AtomicLong();
38 private transient final AtomicInteger _requestsActive = new AtomicInteger();
39 private transient final AtomicInteger _requestsMaxActive = new AtomicInteger();
40 private transient final AtomicInteger _responses1xx = new AtomicInteger();
41 private transient final AtomicInteger _responses2xx = new AtomicInteger();
42 private transient final AtomicInteger _responses3xx = new AtomicInteger();
43 private transient final AtomicInteger _responses4xx = new AtomicInteger();
44 private transient final AtomicInteger _responses5xx = new AtomicInteger();
45 private transient final AtomicLong _responsesTotalBytes = new AtomicLong();
46
47
48
49
50 public void statsReset()
51 {
52 _statsStartedAt.set(System.currentTimeMillis());
53 _requests.set(0);
54 _resumedRequests.set(0);
55 _expiredRequests.set(0);
56 _requestMinTime.set(Long.MAX_VALUE);
57 _requestMaxTime.set(0L);
58 _requestTotalTime.set(0L);
59 _suspendMinTime.set(Long.MAX_VALUE);
60 _suspendTotalTime.set(0L);
61 _requestsActive.set(0);
62 _requestsMaxActive.set(0);
63 _responses1xx.set(0);
64 _responses2xx.set(0);
65 _responses3xx.set(0);
66 _responses4xx.set(0);
67 _responses5xx.set(0);
68 _responsesTotalBytes.set(0L);
69 }
70
71 private void updateMax(AtomicInteger valueHolder, int value)
72 {
73 int oldValue = valueHolder.get();
74 while (value > oldValue)
75 {
76 if (valueHolder.compareAndSet(oldValue, value))
77 break;
78 oldValue = valueHolder.get();
79 }
80 }
81
82 private void updateMax(AtomicLong valueHolder, long value)
83 {
84 long oldValue = valueHolder.get();
85 while (value > oldValue)
86 {
87 if (valueHolder.compareAndSet(oldValue, value))
88 break;
89 oldValue = valueHolder.get();
90 }
91 }
92
93 private void updateMin(AtomicLong valueHolder, long value)
94 {
95 long oldValue = valueHolder.get();
96 while (value < oldValue)
97 {
98 if (valueHolder.compareAndSet(oldValue, value))
99 break;
100 oldValue = valueHolder.get();
101 }
102 }
103
104 public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
105 {
106 _requests.incrementAndGet();
107
108 int activeRequests = _requestsActive.incrementAndGet();
109 updateMax(_requestsMaxActive, activeRequests);
110
111
112
113 AsyncContinuation continuation = request.getAsyncContinuation();
114 if (continuation.isExpired())
115 {
116 _expiredRequests.incrementAndGet();
117 }
118 else if (continuation.isResumed())
119 {
120 _resumedRequests.incrementAndGet();
121
122 long initialTime = request.getTimeStamp();
123 long suspendTime = System.currentTimeMillis() - initialTime;
124 updateMin(_suspendMinTime, suspendTime);
125 _suspendTotalTime.addAndGet(suspendTime);
126 }
127
128 try
129 {
130 super.handle(path, request, httpRequest, httpResponse);
131 }
132 finally
133 {
134 _requestsActive.decrementAndGet();
135
136 if (!continuation.isSuspended())
137 {
138 updateResponse(request);
139 }
140 }
141 }
142
143 private void updateResponse(Request request)
144 {
145 long elapsed = System.currentTimeMillis() - request.getTimeStamp();
146
147 updateMin(_requestMinTime, elapsed);
148 updateMax(_requestMaxTime, elapsed);
149 _requestTotalTime.addAndGet(elapsed);
150
151 Response response = request.getResponse();
152 switch (response.getStatus() / 100)
153 {
154 case 1:
155 _responses1xx.incrementAndGet();
156 break;
157 case 2:
158 _responses2xx.incrementAndGet();
159 break;
160 case 3:
161 _responses3xx.incrementAndGet();
162 break;
163 case 4:
164 _responses4xx.incrementAndGet();
165 break;
166 case 5:
167 _responses5xx.incrementAndGet();
168 break;
169 default:
170 break;
171 }
172
173 _responsesTotalBytes.addAndGet(response.getContentCount());
174 }
175
176 protected void doStart() throws Exception
177 {
178 super.doStart();
179 statsReset();
180 }
181
182
183
184
185
186
187
188 public int getRequests()
189 {
190 return _requests.get();
191 }
192
193
194
195
196
197 public int getRequestsActive()
198 {
199 return _requestsActive.get();
200 }
201
202
203
204
205
206 public int getRequestsActiveMax()
207 {
208 return _requestsMaxActive.get();
209 }
210
211
212
213
214
215 public int getRequestsResumed()
216 {
217 return _resumedRequests.get();
218 }
219
220
221
222
223
224 public int getRequestsExpired()
225 {
226 return _expiredRequests.get();
227 }
228
229
230
231
232
233 public int getResponses1xx()
234 {
235 return _responses1xx.get();
236 }
237
238
239
240
241
242 public int getResponses2xx()
243 {
244 return _responses2xx.get();
245 }
246
247
248
249
250
251 public int getResponses3xx()
252 {
253 return _responses3xx.get();
254 }
255
256
257
258
259
260 public int getResponses4xx()
261 {
262 return _responses4xx.get();
263 }
264
265
266
267
268
269 public int getResponses5xx()
270 {
271 return _responses5xx.get();
272 }
273
274
275
276
277 public long getStatsOnMs()
278 {
279 return System.currentTimeMillis() - _statsStartedAt.get();
280 }
281
282
283
284
285
286 public long getRequestTimeMin()
287 {
288 return _requestMinTime.get();
289 }
290
291
292
293
294
295 public long getRequestTimeMax()
296 {
297 return _requestMaxTime.get();
298 }
299
300
301
302
303
304 public long getRequestTimeTotal()
305 {
306 return _requestTotalTime.get();
307 }
308
309
310
311
312
313
314
315 public long getRequestTimeAverage()
316 {
317 int requests = getRequests();
318 return requests == 0 ? 0 : getRequestTimeTotal() / requests;
319 }
320
321
322
323
324 public long getResponsesBytesTotal()
325 {
326 return _responsesTotalBytes.get();
327 }
328
329
330
331
332
333 public long getSuspendedTimeMin()
334 {
335 return _suspendMinTime.get();
336 }
337
338
339
340
341
342 public long getSuspendedTimeTotal()
343 {
344 return _suspendTotalTime.get();
345 }
346 }