KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > performance > http > load > HttpResponseAnalysisReport


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tctest.performance.http.load;
6
7 import java.io.BufferedInputStream JavaDoc;
8 import java.io.File JavaDoc;
9 import java.io.FileFilter JavaDoc;
10 import java.io.FileInputStream JavaDoc;
11 import java.io.FileNotFoundException JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.ObjectInputStream JavaDoc;
14 import java.net.URL JavaDoc;
15 import java.text.NumberFormat JavaDoc;
16 import java.util.Arrays JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.TreeMap JavaDoc;
20 import java.util.regex.Matcher JavaDoc;
21 import java.util.regex.Pattern JavaDoc;
22 import java.util.zip.GZIPInputStream JavaDoc;
23
24 final class HttpResponseAnalysisReport {
25
26   static final String JavaDoc RESULTS_FILE_PREFIX = "response-statistics";
27   static final String JavaDoc PAD = " ";
28
29   private HttpResponseAnalysisReport() {
30     // cannot instantiate
31
}
32
33   private static class UrlStat {
34     private final IntList times = new IntList();
35     private int errors = 0;
36     private int success = 0;
37
38     void add(ResponseStatistic stat) {
39       times.add(stat.duration());
40       if (stat.statusCode() == 200) {
41         success++;
42       } else {
43         errors++;
44       }
45     }
46   }
47
48   private static class HostStat {
49     private final Map JavaDoc urlStats = new TreeMap JavaDoc();
50
51     void add(String JavaDoc urlKey, ResponseStatistic stat) {
52       UrlStat urlStat = (UrlStat) urlStats.get(urlKey);
53       if (urlStat == null) {
54         urlStat = new UrlStat();
55         urlStats.put(urlKey, urlStat);
56       }
57
58       urlStat.add(stat);
59     }
60
61   }
62
63   private static class StatsIterator implements Iterator JavaDoc {
64
65     private final File JavaDoc[] files;
66     private final Pattern JavaDoc pattern = Pattern.compile("^" + RESULTS_FILE_PREFIX + "\\.(.+)\\.(\\d+)\\.gz$");
67     private final int[] counts;
68     private int index = 0;
69     private GZIPInputStream JavaDoc in;
70
71     public StatsIterator(File JavaDoc resultsDir) {
72       files = resultsDir.listFiles(new FileFilter JavaDoc() {
73         public boolean accept(File JavaDoc pathname) {
74           return pattern.matcher(pathname.getName()).matches();
75         }
76       });
77
78       counts = new int[files.length];
79
80       for (int i = 0; i < files.length; i++) {
81         File JavaDoc file = files[i];
82         Matcher JavaDoc m = pattern.matcher(file.getName());
83         if (!m.matches()) { throw new RuntimeException JavaDoc(file + " doesn't match"); }
84         int count = Integer.parseInt(m.group(2));
85         System.err.println("Going to read " + count + " stats from host " + m.group(1));
86         counts[i] = count;
87       }
88     }
89
90     public boolean hasNext() {
91       for (int i = 0; i < counts.length; i++) {
92         if (counts[i] > 0) { return true; }
93       }
94       return false;
95     }
96
97     public Object JavaDoc next() {
98       try {
99         return next0();
100       } catch (Exception JavaDoc e) {
101         if (e instanceof RuntimeException JavaDoc) { throw (RuntimeException JavaDoc) e; }
102         throw new RuntimeException JavaDoc(e);
103       }
104     }
105
106     private Object JavaDoc next0() throws Exception JavaDoc {
107       if (index >= counts.length) { throw new IllegalStateException JavaDoc("no more data: index = " + index); }
108
109       if (in == null) {
110         in = inputFor(files[index]);
111       }
112
113       if (counts[index] == 0) {
114         index++;
115         in.close();
116         in = inputFor(files[index]);
117       }
118
119       counts[index]--;
120       return new ObjectInputStream JavaDoc(in).readObject();
121     }
122
123     public void remove() {
124       throw new UnsupportedOperationException JavaDoc();
125     }
126
127     public int numClients() {
128       return files.length;
129     }
130
131     private static GZIPInputStream JavaDoc inputFor(File JavaDoc file) throws FileNotFoundException JavaDoc, IOException JavaDoc {
132       return new GZIPInputStream JavaDoc(new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(file)));
133     }
134   }
135
136   public static void printReport(File JavaDoc resultsDir, String JavaDoc testName, int duration) throws IOException JavaDoc {
137     StatsIterator statsIterator = new StatsIterator(resultsDir);
138
139     int count = 0;
140
141     Map JavaDoc hostGroup = new TreeMap JavaDoc();
142     Map JavaDoc fullUrlGroup = new TreeMap JavaDoc();
143
144     long minStart = Long.MAX_VALUE;
145     long maxEnd = -1;
146
147     while (statsIterator.hasNext()) {
148       count++;
149       if ((count % 50000) == 0) {
150         System.err.println("Processed " + count + " stats...");
151       }
152
153       ResponseStatistic stat = (ResponseStatistic) statsIterator.next();
154       minStart = Math.min(stat.startTime(), minStart);
155       maxEnd = Math.max(stat.endTime(), maxEnd);
156
157       // split url parts
158
URL JavaDoc url = new URL JavaDoc(stat.url());
159       String JavaDoc hostKey = url.getHost() + ":" + url.getPort();
160       String JavaDoc urlKey = url.getPath() + url.getQuery();
161
162       // group response times for all unique URLs
163
IntList urlTimes = (IntList) fullUrlGroup.get(urlKey);
164       if (urlTimes == null) {
165         urlTimes = new IntList();
166         fullUrlGroup.put(urlKey, urlTimes);
167       }
168       urlTimes.add(stat.duration());
169
170       //
171
HostStat hostStat = (HostStat) hostGroup.get(hostKey);
172       if (hostStat == null) {
173         hostStat = new HostStat();
174         hostGroup.put(hostKey, hostStat);
175       }
176       hostStat.add(urlKey, stat);
177     }
178
179     int realDuration = (int) ((maxEnd - minStart) / 1000);
180
181     printHeader(resultsDir, testName, realDuration, statsIterator.numClients());
182     out("Throughput Analyze:");
183     out(repeat('_', "Throughput Analyze:".length()));
184
185     Iterator JavaDoc iter = hostGroup.entrySet().iterator();
186     while (iter.hasNext()) {
187       Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
188       String JavaDoc hostKey = (String JavaDoc) entry.getKey();
189       HostStat hostStat = (HostStat) entry.getValue();
190       throughputAnalysis(hostKey, hostStat, realDuration);
191     }
192     nl();
193     nl();
194     out("Response Analyze:");
195     out(repeat('_', "Response Analyze:".length()));
196     responseAnalysis(fullUrlGroup);
197   }
198
199   private static void throughputAnalysis(String JavaDoc key, HostStat hostStat, long duration) {
200     int colWidth = 16;
201     nl();
202     write("(" + key + ")", (42 + key.length()) - ((key.length() + 2) / 2));
203     nl();
204     nl();
205     write("Ave.", colWidth);
206     write("tps", colWidth);
207     write("total", colWidth);
208     write("success", colWidth);
209     write("error", colWidth);
210     nl();
211     out(repeat('-', 80));
212
213     double totalAve = 0;
214     double totalTps = 0;
215     int totalTotal = 0;
216     int totalSuccess = 0;
217     int totalError = 0;
218
219     Iterator JavaDoc iter = hostStat.urlStats.entrySet().iterator();
220     while (iter.hasNext()) {
221       double ave = 0;
222       double tps = 0;
223       long sum = 0;
224
225       Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
226       String JavaDoc urlKey = (String JavaDoc) entry.getKey();
227       UrlStat urlStat = (UrlStat) entry.getValue();
228
229       final IntList times = urlStat.times;
230       final int success = urlStat.success;
231       final int error = urlStat.errors;
232
233       out(urlKey);
234       int size = times.size();
235
236       for (int i = 0; i < size; i++) {
237         sum += times.get(i);
238       }
239
240       double doubleSize = size;
241
242       ave = sum / doubleSize;
243       totalAve += ave;
244       tps = doubleSize / duration;
245       totalTps += tps;
246       totalTotal += doubleSize;
247       totalSuccess += success;
248       totalError += error;
249       writeNum(Math.floor(ave), colWidth);
250       writeNum(tps, colWidth);
251       writeNum(doubleSize, colWidth);
252       writeNum(success, colWidth);
253       writeNum(error, colWidth);
254       nl();
255     }
256     out(repeat('=', 80));
257     write("total", 5);
258     writeNum(Math.floor(totalAve), 11);
259     writeNum(totalTps, colWidth);
260     writeNum(totalTotal, colWidth);
261     writeNum(totalSuccess, colWidth);
262     writeNum(totalError, colWidth);
263     nl();
264     nl();
265   }
266
267   private static void responseAnalysis(Map JavaDoc urlGroup) {
268     int colWidth = 9;
269     nl();
270     write("Ave.", 8);
271     write("S.D.", colWidth);
272     write("min.", colWidth);
273     write("50%", colWidth);
274     write("60%", colWidth);
275     write("70%", colWidth);
276     write("80%", colWidth);
277     write("90%", colWidth);
278     write("max.", colWidth);
279     nl();
280     out(repeat('-', 80));
281
282     for (Iterator JavaDoc iter = urlGroup.entrySet().iterator(); iter.hasNext(); ) {
283       double ave = 0;
284       double size = 0;
285       double squareSum = 0;
286       long sum = 0;
287
288       Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
289       String JavaDoc urlKey = (String JavaDoc) entry.getKey();
290       IntList values = (IntList) entry.getValue();
291       out(urlKey);
292       size = values.size();
293       long[] durationSpread = new long[values.size()];
294
295       for (int i = 0; i < size; i++) {
296         int duration = values.get(i);
297         sum += duration;
298         squareSum += duration * duration;
299         durationSpread[i] = duration;
300       }
301
302       Arrays.sort(durationSpread);
303       ave = sum / size;
304       writeNum(Math.floor(ave), 8);
305       writeNum(Math.floor(Math.sqrt((squareSum / size) - (ave * ave))), colWidth);
306       writeNum(durationSpread[0], colWidth);
307       writeNum(durationSpread[new Float JavaDoc(durationSpread.length * .5f).intValue() - 1], colWidth);
308       writeNum(durationSpread[new Float JavaDoc(durationSpread.length * .6f).intValue() - 1], colWidth);
309       writeNum(durationSpread[new Float JavaDoc(durationSpread.length * .7f).intValue() - 1], colWidth);
310       writeNum(durationSpread[new Float JavaDoc(durationSpread.length * .8f).intValue() - 1], colWidth);
311       writeNum(durationSpread[new Float JavaDoc(durationSpread.length * .9f).intValue() - 1], colWidth);
312       writeNum(durationSpread[durationSpread.length - 1], colWidth);
313       nl();
314     }
315   }
316
317   private static void printHeader(File JavaDoc resultsDir, String JavaDoc testName, int realDuration, int loadClients) {
318     TestProperties props = new TestProperties(resultsDir.getParentFile());
319     String JavaDoc threads = "" + props.getThreadCount();
320     String JavaDoc[] hosts = props.getHosts();
321     String JavaDoc stickyRatio = "" + props.getStickyRatio();
322
323     out("HTTP RESPONSE ANALYSIS REPORT -- " + testName);
324     nl();
325     write("THREADS:", 74);
326     out("" + (Integer.parseInt(threads) * loadClients), 6);
327     write("HOSTS:", 74);
328     out(Integer.toString(hosts.length), 6);
329     write("STICKY-RATIO:", 74);
330     out(stickyRatio, 6);
331     write("DURATION (real):", 74);
332     out("" + realDuration, 6);
333     write("LOAD CLIENTS:", 74);
334     out("" + loadClients, 6);
335   }
336
337   private static void write(String JavaDoc str, int width) {
338     if (str.length() > width) str = str.substring(0, width);
339     System.out.print(pad(width - str.length()) + str);
340   }
341
342   private static void writeNum(double num, int width) {
343     NumberFormat JavaDoc nf = NumberFormat.getInstance();
344     nf.setMaximumFractionDigits(2);
345     String JavaDoc str = nf.format(num);
346     System.out.print(pad(width - str.length()) + str);
347   }
348
349   private static void out(String JavaDoc str) {
350     System.out.println(str);
351   }
352
353   private static void out(String JavaDoc str, int width) {
354     System.out.println(pad(width - str.length()) + str);
355   }
356
357   private static String JavaDoc pad(int width) {
358     String JavaDoc pad = "";
359     for (int i = 0; i < width; i++) {
360       pad += PAD;
361     }
362     return pad;
363   }
364
365   private static String JavaDoc repeat(char chr, int width) {
366     String JavaDoc str = "";
367     for (int i = 0; i < width; i++) {
368       str += chr;
369     }
370     return str;
371   }
372
373   private static void nl() {
374     System.out.print("\n");
375   }
376 }
377
Popular Tags