KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > servlets > LoadCount


1 /******************************************************************************
2  * LoadCount.java
3  * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 package org.openlaszlo.servlets;
11
12 import java.util.Date JavaDoc;
13 import java.util.LinkedList JavaDoc;
14 import java.text.DecimalFormat JavaDoc;
15
16 /**
17  * Thread-safe class to monitor load count. Displays:
18  *
19  * <ul>
20  * <li>...
21  * </ul>
22  */

23 public class LoadCount
24 {
25     public class LoadInfo
26     {
27         // number of requests processed
28
public int m01Requests = 0;
29         public int m05Requests = 0;
30         public int m15Requests = 0;
31
32         // request avg. (requests / second)
33
public float m01RequestAvg = 0;
34         public float m05RequestAvg = 0;
35         public float m15RequestAvg = 0;
36
37         // avg. request time
38
public float m01AvgResTime = 0;
39         public float m05AvgResTime = 0;
40         public float m15AvgResTime = 0;
41
42         // max. request time
43
public float m01MaxResTime = 0;
44         public float m05MaxResTime = 0;
45         public float m15MaxResTime = 0;
46
47         // active requests
48
public int mActiveRequestCount = 0;
49
50         // total count for current bucket
51
public int mCurrentRequestCount = 0;
52         public int mCurrentResponseCount = 0;
53         public int mCurrentResponseTimes = 0;
54
55         // total request/response count since object instantiation
56
public int mTotalRequestCount = 0;
57         public int mTotalResponseCount = 0;
58     }
59
60
61     private static final int SECONDS_PER_MINUTE = 60;
62     private static final int LOAD_01_MINUTES = 1;
63     private static final int LOAD_05_MINUTES = 5;
64     private static final int LOAD_15_MINUTES = 15;
65
66
67     /** Display pattern to apply for floats. */
68     private DecimalFormat JavaDoc mFormat = new DecimalFormat JavaDoc("#.##");
69
70     /** The time when the next sample snapshot should happen. */
71     private long mNext;
72
73     /** Count of active request count. */
74     private int mActiveRequestCount;
75
76     /** Total request count since object creation. */
77     private int mTotalRequestCount;
78
79     /** Total response count since object creation. */
80     private int mTotalResponseCount;
81
82     /** Count of current sample load count. */
83     private int mCurrentRequestCount;
84
85     /** Each bucket represents requests per sample. */
86     private int[] mRequestCount;
87
88     /** Sum of current request times (in milliseconds). */
89     private int mCurrentResponseTimes;
90
91     /** Each bucket represents the sum of request times (in milliseconds) for a
92      * sample interval. */

93     private int[] mResponseTimes;
94
95     /** Current max response time (in milliseconds). */
96     private int mCurrentMaxResponseTime;
97
98     /** Each bucket represents the max response time (in milliseconds) for a
99      * sample interval. */

100     private int[] mMaxResponseTime;
101
102     /** Sum of current request times (in milliseconds). */
103     private int mCurrentResponseCount;
104
105     /** Each bucket represents the sum of request times (in milliseconds) per
106      * sample interval. */

107     private int[] mResponseCount;
108
109     /** Location of array bucket to place the current sample count. */
110     private int mPtr;
111
112     /** Max number of sample slots for array. */
113     private int mMaxSamples;
114
115     /** Seconds per sample. */
116     private int mSecsPerSample;
117
118     /** Millisconds per sample. */
119     private int mMilliSecsPerSample;
120
121     /** Last response time. */
122     private int mLastResponseTime;
123
124     /** Number of buckets used by 1 minute. */
125     private int m01;
126
127     /** Number of buckets used by 5 minutes. */
128     private int m05;
129
130     /** Number of buckets used by 15 minutes. */
131     private int m15;
132
133     /**
134      * Construct a load count with 60 second sampling.
135      */

136     public LoadCount()
137     {
138         this(SECONDS_PER_MINUTE);
139     }
140
141     /**
142      * Construct a load count with a user-defined sampling interval. If the
143      * sampling interval is not divisble by 60 seconds, the following values are
144      * used:
145      *
146      * <ul>
147      * <li>less than 1 => default to 15 secs</li>
148      * <li>greater than a minute => default to 60 secs</li>
149      * <li>not divisible into 60 secs => find the next higher divisible
150      * number</li>
151      * </ul>
152      *
153      * @param secsPerSample the time granularity on how often a load sample
154      * should be taken.
155      */

156     public LoadCount(int secsPerSample)
157     {
158         // Make sure sample interval is a divisor of 60 seconds.
159
if (secsPerSample < 1) {
160             // less than 1 => default to 15 secs
161
secsPerSample = 15;
162         } else if (SECONDS_PER_MINUTE < secsPerSample) {
163             // greater than a minute => default to 60 secs
164
secsPerSample = SECONDS_PER_MINUTE;
165         } else if (SECONDS_PER_MINUTE % secsPerSample != 0) {
166             // not divisible into 60 secs => find the next higher divisible
167
// number
168
while (SECONDS_PER_MINUTE % ++secsPerSample != 0 )
169                 ;
170         }
171
172         mSecsPerSample = secsPerSample;
173         mMilliSecsPerSample = mSecsPerSample * 1000;
174
175         // N sample slots for 15 minutes.
176
mMaxSamples = ( LOAD_15_MINUTES * SECONDS_PER_MINUTE ) / mSecsPerSample;
177         mRequestCount = new int[mMaxSamples];
178         mResponseCount = new int[mMaxSamples];
179         mResponseTimes = new int[mMaxSamples];
180         mMaxResponseTime = new int[mMaxSamples];
181
182         m01 = ( LOAD_01_MINUTES * SECONDS_PER_MINUTE) / mSecsPerSample;
183         m05 = ( LOAD_05_MINUTES * SECONDS_PER_MINUTE) / mSecsPerSample;
184         m15 = ( LOAD_15_MINUTES * SECONDS_PER_MINUTE) / mSecsPerSample;
185
186         // reset all values
187
reset();
188     }
189
190
191     /**
192      * Clear and reset all values.
193      */

194     synchronized public void reset()
195     {
196         mNext = System.currentTimeMillis() + mSecsPerSample;
197         mPtr = 0;
198         mActiveRequestCount = 0;
199         mCurrentRequestCount = 0;
200         mCurrentResponseTimes = 0;
201         mCurrentResponseCount = 0;
202         mCurrentMaxResponseTime = 0;
203         mTotalRequestCount = 0;
204         mTotalResponseCount = 0;
205         mLastResponseTime = -1;
206
207         for (int i=0; i < mMaxSamples; i++) {
208             mRequestCount[i] = 0;
209             mResponseCount[i] = 0;
210             mResponseTimes[i] = 0;
211             mMaxResponseTime[i] = 0;
212         }
213     }
214
215     /**
216      * Check if it's time to count the next sample interval.
217      */

218     private void check()
219     {
220         long now = System.currentTimeMillis();
221         if (mNext <= now) {
222
223             // Ptr to current ptr.
224
int prevPtr = mPtr;
225
226             // (1) find out how many sample intervals it's been. at least one
227
// interval has elapsed or we wouldn't be in here.
228
int n = (int) ( ( now - mNext ) / mMilliSecsPerSample ) + 1;
229
230             // (2.a) calculate and place request time avg
231
// (2.b) add last count to sample bucket
232
// (2.c) check if we have to wrap around arrays
233
mRequestCount[mPtr] = mCurrentRequestCount;
234             mResponseCount[mPtr] = mCurrentResponseCount;
235             mResponseTimes[mPtr] = mCurrentResponseTimes;
236             mMaxResponseTime[mPtr] = mCurrentMaxResponseTime;
237             if (--mPtr < 0)
238                 mPtr = mMaxSamples - 1;
239
240             // (3) zero out rest of buckets during silent interval
241
int count = n-1;
242             while (0 < count--) {
243                 mRequestCount[mPtr] = 0;
244                 mResponseCount[mPtr] = 0;
245                 mResponseTimes[mPtr] = 0;
246                 mMaxResponseTime[mPtr] = 0;
247
248                 // We've zeroed out everything. Don't need to clear things more
249
// than once.
250
if (prevPtr == mPtr)
251                     break;
252
253                 if (--mPtr < 0)
254                     mPtr = mMaxSamples -1;
255             }
256
257             // (4) set next time we need to snap
258
mNext += ( mMilliSecsPerSample * n );
259
260             // (5) clear count
261
mCurrentRequestCount = 0;
262             mCurrentResponseCount = 0;
263             mCurrentResponseTimes = 0;
264
265             // (6) Clear max response time
266
mCurrentMaxResponseTime = 0;
267         }
268     }
269
270
271     /**
272      * Increment load count for the current sample interval giving it a time.
273      * @param t time it took for request to finish.
274      */

275     synchronized public void decrement(int t)
276     {
277         check();
278         --mActiveRequestCount;
279         ++mCurrentResponseCount;
280         mCurrentResponseTimes += t;
281         ++mTotalResponseCount;
282         mLastResponseTime = t;
283
284         if (t > mCurrentMaxResponseTime) {
285             mCurrentMaxResponseTime = t;
286         }
287     }
288
289     /**
290      * Increment load count for the current sample interval.
291      */

292     synchronized public void increment()
293     {
294         check();
295         ++mActiveRequestCount;
296         ++mCurrentRequestCount;
297         ++mTotalRequestCount;
298     }
299
300     synchronized public LoadInfo getLoadInfo()
301     {
302         check();
303
304         LoadInfo li = new LoadInfo();
305
306         int p = mPtr+1;
307         int n = 0;
308         int reqCountSum = 0;
309         int resCountSum = 0;
310         int resTimeSum = 0;
311
312         int maxResponseTime = 0;
313
314         while ( n++ < m15 ) {
315             p %= m15;
316             reqCountSum += mRequestCount[p];
317             resCountSum += mResponseCount[p];
318             resTimeSum += mResponseTimes[p];
319             if (mMaxResponseTime[p] > maxResponseTime) {
320                 maxResponseTime = mMaxResponseTime[p];
321             }
322             p++;
323             if (n == m01) {
324                 li.m01Requests = reqCountSum;
325                 if (reqCountSum != 0)
326                     li.m01RequestAvg = (float)reqCountSum / (float) (LOAD_01_MINUTES * SECONDS_PER_MINUTE);
327                 if (resCountSum != 0)
328                     li.m01AvgResTime = (float)resTimeSum / (float) resCountSum;
329                 li.m01MaxResTime = maxResponseTime;
330             }
331             if (n == m05) {
332                 li.m05Requests = reqCountSum;
333                 if (reqCountSum != 0)
334                     li.m05RequestAvg = (float)reqCountSum / (float) (LOAD_05_MINUTES * SECONDS_PER_MINUTE);
335                 if (resCountSum != 0)
336                     li.m05AvgResTime = (float)resTimeSum / (float) resCountSum;
337                 li.m05MaxResTime = maxResponseTime;
338             }
339             if (n == m15) {
340                 li.m15Requests = reqCountSum;
341                 if (reqCountSum != 0)
342                     li.m15RequestAvg = (float)reqCountSum / (float) (LOAD_15_MINUTES * SECONDS_PER_MINUTE);
343                 if (resCountSum != 0)
344                     li.m15AvgResTime = (float)resTimeSum / (float) resCountSum;
345                 li.m15MaxResTime = maxResponseTime;
346             }
347         }
348
349         li.mActiveRequestCount = mActiveRequestCount;
350         li.mCurrentRequestCount = mCurrentRequestCount;
351         li.mCurrentResponseCount = mCurrentResponseCount;
352         li.mCurrentResponseTimes = mCurrentResponseTimes;
353
354         li.mTotalRequestCount = mTotalRequestCount;
355         li.mTotalResponseCount = mTotalResponseCount;
356
357         return li;
358     }
359
360     /**
361      * Return load information in XML w/o sample interval view.
362      * @param tag tag name
363      */

364     public String JavaDoc toXML(String JavaDoc tag)
365     {
366         return toXML(tag, false);
367     }
368
369     /**
370      * Return load information in XML.
371      * @param tag tag name
372      * @param verbose if true, returns information with all samples.
373      */

374     synchronized public String JavaDoc toXML(String JavaDoc tag, boolean verbose)
375     {
376         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
377         LoadInfo load = getLoadInfo();
378
379         // req: total requests for interval
380
// rps: requests per second during interval
381
// art: average response time (in milliseconds)
382
buf.append("<").append(tag).append(" sample-seconds=\"").append(mSecsPerSample).append("\"")
383             .append(" active-requests=\"").append(load.mActiveRequestCount).append("\"")
384             .append(" last-response-time=\"").append(mLastResponseTime).append("\"")
385             .append(">\n");
386
387         buf.append("<one")
388             .append(" requests=\"").append(load.m01Requests).append("\"")
389             .append(" requests-per-second=\"").append(mFormat.format(load.m01RequestAvg)).append("\"")
390             .append(" avg-response-time=\"").append(mFormat.format(load.m01AvgResTime)).append("\"")
391             .append(" max-response-time=\"").append(mFormat.format(load.m01MaxResTime)).append("\"")
392             .append(" />\n");
393
394         buf.append("<five")
395             .append(" requests=\"").append(load.m05Requests).append("\"")
396             .append(" requests-per-second=\"").append(mFormat.format(load.m05RequestAvg)).append("\"")
397             .append(" avg-response-time=\"").append(mFormat.format(load.m05AvgResTime)).append("\"")
398             .append(" max-response-time=\"").append(mFormat.format(load.m05MaxResTime)).append("\"")
399             .append(" />\n");
400
401         buf.append("<fifteen")
402             .append(" requests=\"").append(load.m15Requests).append("\"")
403             .append(" requests-per-second=\"").append(mFormat.format(load.m15RequestAvg)).append("\"")
404             .append(" avg-response-time=\"").append(mFormat.format(load.m15AvgResTime)).append("\"")
405             .append(" max-response-time=\"").append(mFormat.format(load.m15MaxResTime)).append("\"")
406             .append(" />\n");
407
408         buf.append("<total")
409             .append(" requests=\"").append(load.mTotalRequestCount).append("\"")
410             .append(" responses=\"").append(load.mTotalResponseCount).append("\"")
411             .append(" />\n");
412
413         // sample information
414
// req: total requests for sample
415
// time: sum of requests times during sample (in milliseconds)
416
if (verbose) {
417             buf.append("<samples>\n");
418             int p = mPtr+1;
419             int n = 0;
420             while ( n++ < m15 ) {
421                 p %= m15;
422                 buf.append("<interval")
423                     .append(" n=\"").append(n).append("\"")
424                     .append(" requests=\"").append(mRequestCount[p]).append("\"")
425                     .append(" responses=\"").append(mResponseCount[p]).append("\"")
426                     .append(" response-times-sum=\"").append(mResponseTimes[p]).append("\"")
427                     .append(" />");
428                 p++;
429             }
430             buf.append("</samples>\n");
431         }
432
433         buf.append("</").append(tag).append(">\n");
434
435         return buf.toString();
436     }
437
438
439     /**
440      * See toXML().
441      */

442     public String JavaDoc toString()
443     {
444         return toXML("load");
445     }
446 }
447
Popular Tags