KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > tools > profiler > ProfilerServlet


1 /*
2  * Copyright (c) 1998-2005 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Sam
27  */

28
29
30 package com.caucho.tools.profiler;
31
32 import com.caucho.util.CharBuffer;
33 import com.caucho.util.L10N;
34 import com.caucho.util.Sprintf;
35 import com.caucho.vfs.XmlWriter;
36
37 import javax.servlet.ServletException JavaDoc;
38 import javax.servlet.http.HttpServlet JavaDoc;
39 import javax.servlet.http.HttpServletRequest JavaDoc;
40 import javax.servlet.http.HttpServletResponse JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.util.Collection JavaDoc;
43
44 /**
45  * Html interface to profiling information.
46  */

47 public class ProfilerServlet
48   extends HttpServlet JavaDoc
49 {
50   private static final L10N L = new L10N(ProfilerServlet.class);
51
52   // can do this because an instance of Filter is created for each environment
53
private final ProfilerManager _profilerManager = ProfilerManager.getLocal();
54
55   public ProfilerManager createProfiler()
56   {
57     return _profilerManager;
58   }
59
60   public void init()
61   {
62   }
63
64   protected void doGet(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
65     throws ServletException JavaDoc, IOException JavaDoc
66   {
67     handleRequest(req, res);
68     handleResponse(req, res);
69   }
70
71   protected void doPost(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
72     throws ServletException JavaDoc, IOException JavaDoc
73   {
74     handleRequest(req, res);
75     handleResponse(req, res);
76   }
77
78   protected void handleRequest(HttpServletRequest JavaDoc request,
79                                HttpServletResponse JavaDoc response)
80     throws ServletException JavaDoc, IOException JavaDoc
81   {
82   }
83
84   protected void handleResponse(HttpServletRequest JavaDoc request,
85                                 HttpServletResponse JavaDoc response)
86     throws ServletException JavaDoc, IOException JavaDoc
87   {
88     String JavaDoc format = request.getParameter("format");
89     boolean isXml = "xml".equals(format);
90     
91     response.setContentType("text/html");
92
93     response.setHeader("Cache-Control", "no-cache, post-check=0, pre-check=0");
94     response.setHeader("Pragma", "no-cache");
95     response.setHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
96
97     if (isXml)
98       writeXml(request, response);
99     else
100       writeHtml(request, response);
101   }
102
103   protected void writeHtml(HttpServletRequest JavaDoc request,
104                HttpServletResponse JavaDoc response)
105     throws ServletException JavaDoc, IOException JavaDoc
106   {
107     response.setContentType("text/html");
108
109     String JavaDoc sort = request.getParameter("sort");
110
111     ProfilerNodeComparator comparator;
112
113     if ("count".equals(sort))
114       comparator = new CountComparator();
115     else
116       comparator = new TimeComparator();
117
118     comparator.setDescending(true);
119
120     XmlWriter out = new XmlWriter(response.getWriter());
121
122     out.setStrategy(XmlWriter.HTML);
123     out.setIndenting(false);
124
125     out.println(
126       "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
127
128     String JavaDoc contextPath = request.getContextPath();
129
130     if (contextPath == null || contextPath.length() == 0)
131       contextPath = "/";
132
133     String JavaDoc title = L.l("Profiling Results for {0}", contextPath);
134
135     out.startElement("html");
136
137     out.startElement("head");
138     out.writeElement("title", title);
139
140     out.startElement("style");
141     out.writeAttribute("type", "text/css");
142
143     out.println(
144       "h1 { background: #ccddff; margin : 0 -0.5em 0.25em -0.25em; padding: 0.25em 0.25em; }");
145     out.println(
146       "h2 { background: #ccddff; padding: 0.25em 0.5em; margin : 0.5em -0.5em; }");
147     out.println("table { border-collapse : collapse; }");
148     out.println("th { background : #c78ae6; border-left : 1px; border-right : 1px}");
149     out.println("tr { border-bottom : 1px dotted; }");
150     out.println(".number { text-align : right; }");
151     out.println("table table tr { border-bottom : none; }");
152
153     out.endElement("style");
154
155     out.endElement("head");
156
157     out.startElement("body");
158     out.writeElement("h1", title);
159
160     out.startElement("table");
161     out.writeAttribute("border", 0);
162
163     out.startElement("tr");
164
165     out.writeLineElement("th", L.l("Name"));
166
167     out.writeLineElement("th", L.l("Average Time"));
168     out.writeLineElement("th", L.l("Min Time"));
169     out.writeLineElement("th", L.l("Max Time"));
170     out.writeLineElement("th", L.l("Total Time"));
171
172     out.writeLineElement("th", L.l("Invocation Count"));
173
174     out.endElement("tr");
175
176     Collection JavaDoc<ProfilerNode> children
177       = _profilerManager.getChildProfilerNodes(null, comparator);
178
179     displayChildren(children, comparator, out, 0);
180
181     out.endElement("table");
182
183     out.endElement("body");
184
185     out.endElement("html");
186   }
187
188   private void display(ProfilerNode node,
189                        ProfilerNodeComparator comparator,
190                        XmlWriter out,
191                        int depth)
192   {
193     Collection JavaDoc<ProfilerNode> children
194       = _profilerManager.getChildProfilerNodes(node, comparator);
195
196     long thisTime = node.getTime();
197     long minTime = node.getMinTime();
198     long maxTime = node.getMaxTime();
199
200     long childrenTime = 0;
201
202     for (ProfilerNode child : children) {
203       childrenTime += child.getTime();
204     }
205
206     long totalTime = childrenTime + thisTime;
207
208     long invocationCount = node.getInvocationCount();
209     long averageThisTime;
210     long averageTotalTime;
211     long averageChildrenTime;
212
213     if (invocationCount <= 0) {
214       averageThisTime = -1;
215       averageTotalTime = -1;
216       averageChildrenTime = -1;
217     }
218     else {
219       averageThisTime = thisTime / invocationCount;
220       averageTotalTime = totalTime / invocationCount;
221       averageChildrenTime = childrenTime / invocationCount;
222     }
223
224     out.startElement("tr");
225
226     out.writeAttribute("class", "level" + depth);
227
228     // Name
229

230     out.startLineElement("td");
231
232     out.startElement("table");
233     out.startElement("tr");
234
235     out.startLineElement("td");
236
237     if (depth > 0) {
238       for (int i = depth; i > 0; i--) {
239         out.write("&nbsp;");
240         out.write("&nbsp;");
241       }
242
243       out.write("&rarr;");
244     }
245     out.endLineElement("td");
246
247     out.startLineElement("td");
248     out.writeAttribute("class", "text");
249     out.writeText(node.getName());
250     out.endLineElement("td");
251
252     out.endElement("tr");
253     out.endElement("table");
254
255     out.endLineElement("td");
256
257     out.startLineElement("td");
258     out.writeAttribute("class", "number");
259     if (averageThisTime < 0)
260       out.write("&nbsp;");
261     else {
262       String JavaDoc averageTimeString = createTimeString(averageTotalTime, averageThisTime, averageChildrenTime);
263       out.writeAttribute("title", averageTimeString);
264       printTime(out, averageTotalTime);
265     }
266
267     out.endLineElement("td");
268
269     out.startLineElement("td");
270     out.writeAttribute("class", "number");
271     if (minTime < Long.MAX_VALUE)
272       printTime(out, minTime);
273     else
274       out.print("&nbsp;");
275     out.endLineElement("td");
276
277     out.startLineElement("td");
278     out.writeAttribute("class", "number");
279     if (Long.MIN_VALUE < maxTime)
280       printTime(out, maxTime);
281     else
282       out.print("&nbsp;");
283     out.endLineElement("td");
284
285     out.startLineElement("td");
286     out.writeAttribute("class", "number");
287     String JavaDoc timeString = createTimeString(totalTime, thisTime, childrenTime);
288     out.writeAttribute("title", timeString);
289     printTime(out, totalTime);
290     out.endLineElement("td");
291
292     out.startLineElement("td");
293     out.writeAttribute("class", "number");
294     out.print(invocationCount);
295     out.endLineElement("td");
296
297     out.endElement("tr");
298
299     // All children
300

301     displayChildren(children, comparator, out, depth + 1);
302   }
303
304   protected void writeXml(HttpServletRequest JavaDoc request,
305                HttpServletResponse JavaDoc response)
306     throws ServletException JavaDoc, IOException JavaDoc
307   {
308     ProfilerNodeComparator comparator = new TimeComparator();
309
310     comparator.setDescending(true);
311
312     XmlWriter out = new XmlWriter(response.getWriter());
313
314     out.setStrategy(XmlWriter.XML);
315     out.setIndenting(false);
316
317     String JavaDoc contextPath = request.getContextPath();
318
319     if (contextPath == null || contextPath.length() == 0)
320       contextPath = "/";
321
322     out.startElement("profile");
323     out.writeLineElement("name", contextPath);
324
325     Collection JavaDoc<ProfilerNode> children
326       = _profilerManager.getChildProfilerNodes(null, comparator);
327
328     for (ProfilerNode child : children)
329       displayXml(child, comparator, out);
330
331     out.endElement("profile");
332   }
333
334   private void displayXml(ProfilerNode node,
335               ProfilerNodeComparator comparator,
336               XmlWriter out)
337   {
338     Collection JavaDoc<ProfilerNode> children
339       = _profilerManager.getChildProfilerNodes(node, comparator);
340
341     long thisTime = node.getTime();
342     long minTime = node.getMinTime();
343     long maxTime = node.getMaxTime();
344
345     long childrenTime = 0;
346
347     for (ProfilerNode child : children) {
348       childrenTime += child.getTime();
349     }
350
351     long totalTime = childrenTime + thisTime;
352
353     long invocationCount = node.getInvocationCount();
354
355     out.startBlockElement("node");
356     out.writeLineElement("name", node.getName());
357
358     if (minTime < Long.MAX_VALUE)
359       out.writeLineElement("min-time", String.valueOf(minTime));
360     else
361       out.writeLineElement("min-time", "0");
362     if (maxTime >= 0)
363       out.writeLineElement("max-time", String.valueOf(maxTime));
364     else
365       out.writeLineElement("max-time", "0");
366     out.writeLineElement("time", String.valueOf(thisTime));
367     out.writeLineElement("total-time", String.valueOf(totalTime));
368     out.writeLineElement("children-time", String.valueOf(childrenTime));
369     out.writeLineElement("count", String.valueOf(invocationCount));
370
371     for (ProfilerNode child : children)
372       displayXml(child, comparator, out);
373     
374     out.endBlockElement("node");
375   }
376
377   private String JavaDoc createTimeString(long totalTime,
378                                   long thisTime,
379                                   long childrenTime)
380   {
381     CharBuffer cb = new CharBuffer();
382
383     cb.append("totalTime=");
384     formatTime(cb, totalTime);
385
386     cb.append(" thisTime=");
387     formatTime(cb, thisTime);
388
389     cb.append(" childrenTime=");
390     formatTime(cb, childrenTime);
391
392     return cb.toString();
393   }
394
395   private void displayChildren(Collection JavaDoc<ProfilerNode> children,
396                                ProfilerNodeComparator comparator,
397                                XmlWriter out,
398                                int depth)
399   {
400     // All children
401

402     for (ProfilerNode child : children)
403       display(child, comparator, out, depth);
404   }
405
406   private void printTime(XmlWriter out, long time)
407   {
408     CharBuffer cb = new CharBuffer();
409     formatTime(cb, time);
410     out.writeText(cb.toString());
411   }
412
413   private void formatTime(CharBuffer cb, long nanoseconds)
414   {
415     long milliseconds = nanoseconds / 1000000;
416
417     long minutes = milliseconds / 1000 / 60;
418
419     if (minutes > 0) {
420       Sprintf.sprintf(cb, "%d:", minutes);
421       milliseconds -= minutes * 60 * 1000;
422     }
423
424     long seconds = milliseconds / 1000;
425
426     if (minutes > 0)
427       Sprintf.sprintf(cb, "%02d.", seconds);
428     else
429       Sprintf.sprintf(cb, "%d.", seconds);
430
431     milliseconds -= seconds * 1000;
432
433     Sprintf.sprintf(cb, "%03d", milliseconds);
434   }
435 }
436
Popular Tags