KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > util > OpTimerUtil


1 package com.protomatter.util;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.io.*;
54 import java.net.*;
55 import java.sql.*;
56 import java.util.*;
57 import java.text.*;
58
59 import com.protomatter.util.*;
60
61 /**
62  * A utility class for parsing log files with timer traces.
63  * Run this class as follows for a usage display:<P>
64  *
65  * <PRE>
66  * java com.protomatter.util.OpTimerUtil
67  * </PRE>
68  *
69  * Example output looks like the following:<P>
70  *
71  * <PRE><font size="-1"><B>
72  * Reading file "file.txt"
73  * Parsed 2843 lines.
74  * Found 1 unique timer names
75  * Found 2843 timer traces
76  *
77  * Timing information:
78  * ---------------------------------------------------------------------------
79  * OpTimer: My timer
80  * count = 2,843
81  * total = 222,946 ms
82  * min = 0 ms
83  * max = 360 ms
84  * median = 65 ms
85  * average = 78.42 ms
86  *
87  * Histogram:
88  * Median: ------------v
89  * Average: --------------v
90  * 132 o o
91  * o ooo o o
92  * ooooo o ooo o
93  * 88 oooooooo oooooo
94  * ooooooooooooooooooo
95  * ooooooooooooooooooooo
96  * 44 ooooooooooooooooooooooooo o
97  * ooooooooooooooooooooooooooooooo
98  * oooooooooooooooooooooooooooooooooooooo o
99  * count 0 ooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooo oo o
100  * | | | | | | |
101  * millis 0 58 116 175 233 291 349
102  *
103  * </B></font></PRE><P>
104  *
105  * The graph axes are automatically scaled for the data being parsed. This
106  * can be very useful for gathering statistics from log files to determine
107  * system bottlenecks.<P>
108  *
109  * Command line options include the ability to only display analytic data for
110  * a subset of the timers traced in a given log file.
111  *
112  * @see OpTimer
113  */

114 public class OpTimerUtil
115 {
116   private static Map countMap = new HashMap();
117   private static Map totalMap = new HashMap();
118   private static Map minMap = new HashMap();
119   private static Map maxMap = new HashMap();
120   private static Map dataMap = new HashMap();
121   private static Collator collator = null;
122   private static Set nameSet = null;
123   private static Map nameMap = new HashMap();
124   private static Set displayNameSet = new HashSet();
125
126   static
127   {
128     collator = Collator.getInstance(new Locale("en", "US", ""));
129     nameSet = new TreeSet(collator);
130   }
131
132   /**
133    * Private constructor so people don't go around creating these.
134    */

135   private OpTimerUtil()
136   {
137   }
138
139   private static void usage()
140   {
141     System.out.println("");
142     System.out.println("Usage:");
143     System.out.println(" java com.protomatter.util.OpTimer logfile.txt [timer_name_1 ... timer_name_N]");
144     System.out.println("");
145     System.out.println("This program examines the given logfile to find all timers and then displays");
146     System.out.println("aggregate timing information. Number of occurrences, min, max, and average");
147     System.out.println("times are reported.");
148     System.out.println("");
149     System.out.println("If timers are named on the command line, then only those timers will be");
150     System.out.println("analyzed. If none are named on the command line, then all timers found");
151     System.out.println("in the log file will be analyzed.");
152     System.exit(0);
153   }
154
155   public static void main(String JavaDoc args[])
156   {
157     if (args.length == 0)
158       usage();
159
160     for (int i=1; i<args.length; i++)
161       displayNameSet.add(args[i]);
162
163     try
164     {
165       System.out.println("Reading file \"" + args[0] + "\"");
166       long startTime = System.currentTimeMillis();
167       BufferedReader reader = new BufferedReader(
168         new FileReader(new File(args[0])));
169
170       String JavaDoc timerName = null;
171       long elapsed = 0;
172       String JavaDoc line = null;
173       long numLines = 0;
174       long numFound = 0;
175       int index0;
176       int index;
177       int index2;
178       int index3;
179       int index4;
180       String JavaDoc elapsedString = null;
181       while ((line = reader.readLine()) != null)
182       {
183         numLines++;
184
185         index = 0;
186         while ((index0 = line.indexOf("OpTimer[", index)) != -1)
187         {
188           index = index0 + 8;
189           index2 = line.indexOf(", thread=", index);
190           if (index2 != -1)
191           {
192             timerName = line.substring(index, index2);
193             index = index2 + 9;
194             index3 = line.indexOf(", took ", index);
195             if (index3 != -1)
196             {
197               index = index3 + 7;
198               index4 = line.indexOf("ms]", index);
199               if (index4 != -1)
200               {
201                 elapsedString = line.substring(index, index4);
202                 index = index4 + 3;
203                 try
204                 {
205                   elapsed = Long.parseLong(elapsedString);
206                   ++numFound;
207                   handleMatch(timerName, elapsed);
208                 }
209                 catch (Exception JavaDoc x) { ; }
210               }
211             }
212             else
213             {
214               index = index2;
215             }
216           }
217           else
218           {
219             index2 = line.indexOf(", took ", index);
220             if (index2 != -1)
221             {
222               timerName = line.substring(index, index2);
223               index = index2 + 7;
224               index3 = line.indexOf("ms]", index);
225               if (index3 != -1)
226               {
227                 elapsedString = line.substring(index, index3);
228                 index = index3 + 3;
229                 try
230                 {
231                   elapsed = Long.parseLong(elapsedString);
232                   ++numFound;
233                   handleMatch(timerName, elapsed);
234                 }
235                 catch (Exception JavaDoc x) { ; }
236               }
237             }
238           }
239         }
240       }
241       reader.close();
242       startTime = System.currentTimeMillis() - startTime;
243       double parseTime = ((double)startTime) / (double)1000;
244
245       DecimalFormat numberFormat = new DecimalFormat("###,###,###,###,##0.00");
246       DecimalFormat longFormat = new DecimalFormat("###,###,###,###,##0");
247
248       System.out.println("Parse took " + numberFormat.format(parseTime) + " sec.");
249       System.out.println("Parsed " + longFormat.format(numLines) + " lines.");
250       System.out.println("Found " + longFormat.format(nameSet.size()) + " unique timer names");
251       System.out.println("Found " + longFormat.format(numFound) + " timer traces");
252       System.out.println("");
253       System.out.println("Timing information:");
254
255       Iterator i = null;
256       if (displayNameSet.size() > 0)
257         i = displayNameSet.iterator();
258       else
259         i = nameSet.iterator();
260
261       int timerId = 0;
262       while (i.hasNext())
263       {
264         timerName = (String JavaDoc)i.next();
265         if (!nameSet.contains(timerName))
266           continue;
267
268         ++timerId;
269
270         long min = ((Long JavaDoc)minMap.get(timerName)).longValue();
271         long max = ((Long JavaDoc)maxMap.get(timerName)).longValue();
272         long count = ((Long JavaDoc)countMap.get(timerName)).longValue();
273         long total = ((Long JavaDoc)totalMap.get(timerName)).longValue();
274         List data = (List)dataMap.get(timerName);
275
276         Collections.sort(data,
277           new Comparator()
278           {
279             public int compare(Object JavaDoc o1, Object JavaDoc o2)
280             {
281               long l1 = ((Long JavaDoc)o1).longValue();
282               long l2 = ((Long JavaDoc)o2).longValue();
283               if (l1 < l2) return -1;
284               if (l1 == l2) return 0;
285               return 1;
286             }
287             public boolean equals(Object JavaDoc o) { return false; }
288           });
289
290         long median = ((Long JavaDoc)data.get(data.size() /2)).longValue();
291
292         double average = ((double)total)/((double)count);
293
294         System.out.println("---------------------------------------------------------------------------");
295         System.out.println("OpTimer: " + timerName);
296         System.out.println(" count = " + longFormat.format(count));
297         System.out.println(" total = " + longFormat.format(total) + " ms");
298         System.out.println(" min = " + longFormat.format(min) + " ms");
299         System.out.println(" max = " + longFormat.format(max) + " ms");
300         System.out.println(" median = " + longFormat.format(median) + " ms");
301         System.out.println(" average = " + numberFormat.format(average) + " ms");
302         System.out.println("");
303         System.out.println(" Histogram:");
304         histogram(timerName, 80, 10);
305         System.out.println("");
306         System.out.println("");
307       }
308     }
309     catch (Exception JavaDoc x)
310     {
311       x.printStackTrace();
312     }
313   }
314
315   private static void histogram(String JavaDoc timerName, int size, int height)
316   {
317     size -= 12;
318     long min = ((Long JavaDoc)minMap.get(timerName)).longValue();
319     long max = ((Long JavaDoc)maxMap.get(timerName)).longValue();
320     long count = ((Long JavaDoc)countMap.get(timerName)).longValue();
321     long total = ((Long JavaDoc)totalMap.get(timerName)).longValue();
322     double average = ((double)total)/((double)count);
323     List data = (List)dataMap.get(timerName);
324     double width = ((double)max) - ((double)min);
325     double bucket = width / (double)size;
326     double point;
327
328     size++;
329     int graph[] = new int[size];
330     int middle = data.size() /2;
331     double middlePoint = (double)((Long JavaDoc)data.get(middle)).longValue();
332
333     for (int i=0; i<data.size(); i++)
334     {
335       point = (double)(((Long JavaDoc)data.get(i)).longValue() - min);
336       int position = (int)(point / bucket);
337       graph[position]++;
338     }
339
340     int top = 0;
341     for (int i=0; i<size; i++)
342     {
343       if (graph[i] > top)
344         top = graph[i];
345     }
346
347     DecimalFormat yFormat = new DecimalFormat("#########");
348     DecimalFormat xFormat = new DecimalFormat("#######");
349     double heightBucket = ((double)top)/((double)height);
350
351     System.out.print(right("Median: ", 10));
352     boolean mid = false;
353     for (int x=0; x<=size && !mid; x++)
354     {
355       double val = (bucket * (double)x) + (double)min;
356       double nextVal = (bucket * (double)(x +1)) + (double)min;
357       if ((val <= middlePoint) && (middlePoint < nextVal))
358       {
359         System.out.println("v");
360         mid = true;
361       }
362       else if (val < average)
363       {
364         System.out.print("-");
365       }
366     }
367
368     System.out.print(right("Average: ", 10));
369     boolean avg = false;
370     for (int x=0; x<=size && !avg; x++)
371     {
372       double val = (bucket * (double)x) + (double)min;
373       double nextVal = (bucket * (double)(x +1)) + (double)min;
374       if ((val <= average) && (average < nextVal))
375       {
376         System.out.println("v");
377         avg = true;
378       }
379       else if (val < average)
380       {
381         System.out.print("-");
382       }
383     }
384
385     for (int y=(height-1); y>=0; y--)
386     {
387       if ((y % 3) == 0)
388       {
389         double localMin = (heightBucket * (double)y) + (double)min;
390         if (y == 0)
391         {
392           System.out.print(right("count 0", 9));
393         }
394         else
395         {
396           System.out.print(right(yFormat.format(localMin), 9));
397         }
398       }
399       else
400       {
401         System.out.print(right("", 9));
402       }
403
404       System.out.print(" ");
405       for (int x=0; x<size; x++)
406       {
407         if (graph[x] > (int)(heightBucket * (double)y))
408           System.out.print("o");
409         else
410           System.out.print(" ");
411       }
412       System.out.println("");
413     }
414
415     int xTick = 11;
416     System.out.print(left("", 10));
417     for (int x=0; x<=size; x++)
418     {
419       if ((x%xTick) == 0)
420       {
421         if (x == 0)
422         {
423          System.out.print("|");
424         }
425         else
426         {
427           System.out.print(right("|", xTick));
428         }
429       }
430     }
431     System.out.println("");
432
433     System.out.print(right("millis ", 10));
434     for (int x=0; x<=size; x++)
435     {
436       if ((x%xTick) == 0)
437       {
438         if (x == 0)
439         {
440           System.out.print("0");
441         }
442         else
443         {
444           System.out.print(right(xFormat.format((bucket * x) + min), xTick));
445         }
446       }
447     }
448     System.out.println("");
449   }
450
451   private static String JavaDoc left(String JavaDoc text, int width)
452   {
453     StringBuffer JavaDoc b = new StringBuffer JavaDoc(width);
454     b.append(text);
455     int size = width - text.length();
456     for (int i=0; i<size; i++)
457       b.append(" ");
458     return b.toString();
459   }
460
461   private static String JavaDoc right(String JavaDoc text, int width)
462   {
463     StringBuffer JavaDoc b = new StringBuffer JavaDoc(width);
464     int size = width - text.length();
465     for (int i=0; i<size; i++)
466       b.append(" ");
467     b.append(text);
468     return b.toString();
469   }
470
471   private static void handleMatch(String JavaDoc timerName, long elapsed)
472   {
473     if ((displayNameSet.size() > 0) && (!displayNameSet.contains(timerName)))
474       return;
475
476     nameSet.add(timerName);
477
478     List data = (List)dataMap.get(timerName);
479     if (data == null)
480     {
481       data = new ArrayList();
482       dataMap.put(timerName, data);
483     }
484     data.add(new Long JavaDoc(elapsed));
485     Long JavaDoc longVal = (Long JavaDoc)totalMap.get(timerName);
486     if (longVal == null)
487     {
488       longVal = new Long JavaDoc(elapsed);
489     }
490     else
491     {
492       longVal = new Long JavaDoc(longVal.longValue() + elapsed);
493     }
494     totalMap.put(timerName, longVal);
495
496     longVal = (Long JavaDoc)countMap.get(timerName);
497     if (longVal == null)
498     {
499       longVal = new Long JavaDoc(1);
500     }
501     else
502     {
503     longVal = new Long JavaDoc(longVal.longValue() + 1);
504     }
505     countMap.put(timerName, longVal);
506
507     longVal = (Long JavaDoc)minMap.get(timerName);
508     if (longVal == null)
509     {
510       longVal = new Long JavaDoc(elapsed);
511     }
512     else
513     {
514       if (longVal.longValue() > elapsed)
515         longVal = new Long JavaDoc(elapsed);
516     }
517     minMap.put(timerName, longVal);
518
519     longVal = (Long JavaDoc)maxMap.get(timerName);
520     if (longVal == null)
521     {
522       longVal = new Long JavaDoc(elapsed);
523     }
524     else
525     {
526       if (longVal.longValue() < elapsed)
527         longVal = new Long JavaDoc(elapsed);
528     }
529     maxMap.put(timerName, longVal);
530   }
531 }
532
Popular Tags