001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.manager;
019:
020: import java.io.IOException;
021: import java.io.PrintWriter;
022: import java.lang.reflect.Method;
023: import java.text.MessageFormat;
024: import java.util.Date;
025: import java.util.Enumeration;
026: import java.util.Iterator;
027: import java.util.Set;
028: import java.util.Vector;
029:
030: import javax.management.MBeanServer;
031: import javax.management.ObjectInstance;
032: import javax.management.ObjectName;
033: import javax.servlet.ServletException;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import org.apache.catalina.util.RequestUtil;
037:
038: /**
039: * This is a refactoring of the servlet to externalize
040: * the output into a simple class. Although we could
041: * use XSLT, that is unnecessarily complex.
042: *
043: * @author Peter Lin
044: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
045: */
046:
047: public class StatusTransformer {
048:
049: // --------------------------------------------------------- Public Methods
050:
051: public static void setContentType(HttpServletResponse response,
052: int mode) {
053: if (mode == 0) {
054: response.setContentType("text/html;charset="
055: + Constants.CHARSET);
056: } else if (mode == 1) {
057: response.setContentType("text/xml;charset="
058: + Constants.CHARSET);
059: }
060: }
061:
062: /**
063: * Process a GET request for the specified resource.
064: *
065: * @param request The servlet request we are processing
066: * @param response The servlet response we are creating
067: *
068: * @exception IOException if an input/output error occurs
069: * @exception ServletException if a servlet-specified error occurs
070: */
071: public static void writeHeader(PrintWriter writer, int mode) {
072: if (mode == 0) {
073: // HTML Header Section
074: writer.print(Constants.HTML_HEADER_SECTION);
075: } else if (mode == 1) {
076: writer.write(Constants.XML_DECLARATION);
077: writer.write(Constants.XML_STYLE);
078: writer.write("<status>");
079: }
080: }
081:
082: /**
083: * Write the header body. XML output doesn't bother
084: * to output this stuff, since it's just title.
085: *
086: * @param writer The output writer
087: * @param args What to write
088: * @param mode 0 means write
089: */
090: public static void writeBody(PrintWriter writer, Object[] args,
091: int mode) {
092: if (mode == 0) {
093: writer.print(MessageFormat.format(
094: Constants.BODY_HEADER_SECTION, args));
095: }
096: }
097:
098: /**
099: * Write the manager webapp information.
100: *
101: * @param writer The output writer
102: * @param args What to write
103: * @param mode 0 means write
104: */
105: public static void writeManager(PrintWriter writer, Object[] args,
106: int mode) {
107: if (mode == 0) {
108: writer.print(MessageFormat.format(
109: Constants.MANAGER_SECTION, args));
110: }
111: }
112:
113: public static void writePageHeading(PrintWriter writer,
114: Object[] args, int mode) {
115: if (mode == 0) {
116: writer.print(MessageFormat.format(
117: Constants.SERVER_HEADER_SECTION, args));
118: }
119: }
120:
121: public static void writeServerInfo(PrintWriter writer,
122: Object[] args, int mode) {
123: if (mode == 0) {
124: writer.print(MessageFormat.format(
125: Constants.SERVER_ROW_SECTION, args));
126: }
127: }
128:
129: /**
130: *
131: */
132: public static void writeFooter(PrintWriter writer, int mode) {
133: if (mode == 0) {
134: // HTML Tail Section
135: writer.print(Constants.HTML_TAIL_SECTION);
136: } else if (mode == 1) {
137: writer.write("</status>");
138: }
139: }
140:
141: /**
142: * Write the OS state. Mode 0 will generate HTML.
143: * Mode 1 will generate XML.
144: */
145: public static void writeOSState(PrintWriter writer, int mode) {
146: long[] result = new long[16];
147: boolean ok = false;
148: try {
149: String methodName = "info";
150: Class paramTypes[] = new Class[1];
151: paramTypes[0] = result.getClass();
152: Object paramValues[] = new Object[1];
153: paramValues[0] = result;
154: Method method = Class.forName("org.apache.tomcat.jni.OS")
155: .getMethod(methodName, paramTypes);
156: method.invoke(null, paramValues);
157: ok = true;
158: } catch (Throwable t) {
159: // Ignore
160: }
161:
162: if (ok) {
163: if (mode == 0) {
164: writer.print("<h1>OS</h1>");
165:
166: writer.print("<p>");
167: writer.print(" Physical memory: ");
168: writer.print(formatSize(new Long(result[0]), true));
169: writer.print(" Available memory: ");
170: writer.print(formatSize(new Long(result[1]), true));
171: writer.print(" Total page file: ");
172: writer.print(formatSize(new Long(result[2]), true));
173: writer.print(" Free page file: ");
174: writer.print(formatSize(new Long(result[3]), true));
175: writer.print(" Memory load: ");
176: writer.print(new Long(result[6]));
177: writer.print("<br>");
178: writer.print(" Process kernel time: ");
179: writer.print(formatTime(new Long(result[11] / 1000),
180: true));
181: writer.print(" Process user time: ");
182: writer.print(formatTime(new Long(result[12] / 1000),
183: true));
184: writer.print("</p>");
185: } else if (mode == 1) {
186: }
187: }
188:
189: }
190:
191: /**
192: * Write the VM state. Mode 0 will generate HTML.
193: * Mode 1 will generate XML.
194: */
195: public static void writeVMState(PrintWriter writer, int mode)
196: throws Exception {
197:
198: if (mode == 0) {
199: writer.print("<h1>JVM</h1>");
200:
201: writer.print("<p>");
202: writer.print(" Free memory: ");
203: writer.print(formatSize(new Long(Runtime.getRuntime()
204: .freeMemory()), true));
205: writer.print(" Total memory: ");
206: writer.print(formatSize(new Long(Runtime.getRuntime()
207: .totalMemory()), true));
208: writer.print(" Max memory: ");
209: writer.print(formatSize(new Long(Runtime.getRuntime()
210: .maxMemory()), true));
211: writer.print("</p>");
212: } else if (mode == 1) {
213: writer.write("<jvm>");
214:
215: writer.write("<memory");
216: writer.write(" free='" + Runtime.getRuntime().freeMemory()
217: + "'");
218: writer.write(" total='"
219: + Runtime.getRuntime().totalMemory() + "'");
220: writer.write(" max='" + Runtime.getRuntime().maxMemory()
221: + "'/>");
222:
223: writer.write("</jvm>");
224: }
225:
226: }
227:
228: /**
229: * Write connector state.
230: */
231: public static void writeConnectorState(PrintWriter writer,
232: ObjectName tpName, String name, MBeanServer mBeanServer,
233: Vector globalRequestProcessors, Vector requestProcessors,
234: int mode) throws Exception {
235:
236: if (mode == 0) {
237: writer.print("<h1>");
238: writer.print(name);
239: writer.print("</h1>");
240:
241: writer.print("<p>");
242: writer.print(" Max threads: ");
243: writer
244: .print(mBeanServer.getAttribute(tpName,
245: "maxThreads"));
246: writer.print(" Current thread count: ");
247: writer.print(mBeanServer.getAttribute(tpName,
248: "currentThreadCount"));
249: writer.print(" Current thread busy: ");
250: writer.print(mBeanServer.getAttribute(tpName,
251: "currentThreadsBusy"));
252: try {
253: Object value = mBeanServer.getAttribute(tpName,
254: "keepAliveCount");
255: writer.print(" Keeped alive sockets count: ");
256: writer.print(value);
257: } catch (Exception e) {
258: // Ignore
259: }
260:
261: writer.print("<br>");
262:
263: ObjectName grpName = null;
264:
265: Enumeration enumeration = globalRequestProcessors
266: .elements();
267: while (enumeration.hasMoreElements()) {
268: ObjectName objectName = (ObjectName) enumeration
269: .nextElement();
270: if (name.equals(objectName.getKeyProperty("name"))) {
271: grpName = objectName;
272: }
273: }
274:
275: if (grpName == null) {
276: return;
277: }
278:
279: writer.print(" Max processing time: ");
280: writer.print(formatTime(mBeanServer.getAttribute(grpName,
281: "maxTime"), false));
282: writer.print(" Processing time: ");
283: writer.print(formatTime(mBeanServer.getAttribute(grpName,
284: "processingTime"), true));
285: writer.print(" Request count: ");
286: writer.print(mBeanServer.getAttribute(grpName,
287: "requestCount"));
288: writer.print(" Error count: ");
289: writer.print(mBeanServer
290: .getAttribute(grpName, "errorCount"));
291: writer.print(" Bytes received: ");
292: writer.print(formatSize(mBeanServer.getAttribute(grpName,
293: "bytesReceived"), true));
294: writer.print(" Bytes sent: ");
295: writer.print(formatSize(mBeanServer.getAttribute(grpName,
296: "bytesSent"), true));
297: writer.print("</p>");
298:
299: writer
300: .print("<table border=\"0\"><tr><th>Stage</th><th>Time</th><th>B Sent</th><th>B Recv</th><th>Client</th><th>VHost</th><th>Request</th></tr>");
301:
302: enumeration = requestProcessors.elements();
303: while (enumeration.hasMoreElements()) {
304: ObjectName objectName = (ObjectName) enumeration
305: .nextElement();
306: if (name.equals(objectName.getKeyProperty("worker"))) {
307: writer.print("<tr>");
308: writeProcessorState(writer, objectName,
309: mBeanServer, mode);
310: writer.print("</tr>");
311: }
312: }
313:
314: writer.print("</table>");
315:
316: writer.print("<p>");
317: writer
318: .print("P: Parse and prepare request S: Service F: Finishing R: Ready K: Keepalive");
319: writer.print("</p>");
320: } else if (mode == 1) {
321: writer.write("<connector name='" + name + "'>");
322:
323: writer.write("<threadInfo ");
324: writer.write(" maxThreads=\""
325: + mBeanServer.getAttribute(tpName, "maxThreads")
326: + "\"");
327: writer.write(" currentThreadCount=\""
328: + mBeanServer.getAttribute(tpName,
329: "currentThreadCount") + "\"");
330: writer.write(" currentThreadsBusy=\""
331: + mBeanServer.getAttribute(tpName,
332: "currentThreadsBusy") + "\"");
333: writer.write(" />");
334:
335: ObjectName grpName = null;
336:
337: Enumeration enumeration = globalRequestProcessors
338: .elements();
339: while (enumeration.hasMoreElements()) {
340: ObjectName objectName = (ObjectName) enumeration
341: .nextElement();
342: if (name.equals(objectName.getKeyProperty("name"))) {
343: grpName = objectName;
344: }
345: }
346:
347: if (grpName != null) {
348:
349: writer.write("<requestInfo ");
350: writer.write(" maxTime=\""
351: + mBeanServer.getAttribute(grpName, "maxTime")
352: + "\"");
353: writer.write(" processingTime=\""
354: + mBeanServer.getAttribute(grpName,
355: "processingTime") + "\"");
356: writer.write(" requestCount=\""
357: + mBeanServer.getAttribute(grpName,
358: "requestCount") + "\"");
359: writer.write(" errorCount=\""
360: + mBeanServer.getAttribute(grpName,
361: "errorCount") + "\"");
362: writer.write(" bytesReceived=\""
363: + mBeanServer.getAttribute(grpName,
364: "bytesReceived") + "\"");
365: writer.write(" bytesSent=\""
366: + mBeanServer
367: .getAttribute(grpName, "bytesSent")
368: + "\"");
369: writer.write(" />");
370:
371: writer.write("<workers>");
372: enumeration = requestProcessors.elements();
373: while (enumeration.hasMoreElements()) {
374: ObjectName objectName = (ObjectName) enumeration
375: .nextElement();
376: if (name
377: .equals(objectName.getKeyProperty("worker"))) {
378: writeProcessorState(writer, objectName,
379: mBeanServer, mode);
380: }
381: }
382: writer.write("</workers>");
383: }
384:
385: writer.write("</connector>");
386: }
387:
388: }
389:
390: /**
391: * Write processor state.
392: */
393: protected static void writeProcessorState(PrintWriter writer,
394: ObjectName pName, MBeanServer mBeanServer, int mode)
395: throws Exception {
396:
397: Integer stageValue = (Integer) mBeanServer.getAttribute(pName,
398: "stage");
399: int stage = stageValue.intValue();
400: boolean fullStatus = true;
401: boolean showRequest = true;
402: String stageStr = null;
403:
404: switch (stage) {
405:
406: case (1/*org.apache.coyote.Constants.STAGE_PARSE*/):
407: stageStr = "P";
408: fullStatus = false;
409: break;
410: case (2/*org.apache.coyote.Constants.STAGE_PREPARE*/):
411: stageStr = "P";
412: fullStatus = false;
413: break;
414: case (3/*org.apache.coyote.Constants.STAGE_SERVICE*/):
415: stageStr = "S";
416: break;
417: case (4/*org.apache.coyote.Constants.STAGE_ENDINPUT*/):
418: stageStr = "F";
419: break;
420: case (5/*org.apache.coyote.Constants.STAGE_ENDOUTPUT*/):
421: stageStr = "F";
422: break;
423: case (7/*org.apache.coyote.Constants.STAGE_ENDED*/):
424: stageStr = "R";
425: fullStatus = false;
426: break;
427: case (6/*org.apache.coyote.Constants.STAGE_KEEPALIVE*/):
428: stageStr = "K";
429: fullStatus = true;
430: showRequest = false;
431: break;
432: case (0/*org.apache.coyote.Constants.STAGE_NEW*/):
433: stageStr = "R";
434: fullStatus = false;
435: break;
436: default:
437: // Unknown stage
438: stageStr = "?";
439: fullStatus = false;
440:
441: }
442:
443: if (mode == 0) {
444: writer.write("<td><strong>");
445: writer.write(stageStr);
446: writer.write("</strong></td>");
447:
448: if (fullStatus) {
449: writer.write("<td>");
450: writer.print(formatTime(mBeanServer.getAttribute(pName,
451: "requestProcessingTime"), false));
452: writer.write("</td>");
453: writer.write("<td>");
454: if (showRequest) {
455: writer.print(formatSize(mBeanServer.getAttribute(
456: pName, "requestBytesSent"), false));
457: } else {
458: writer.write("?");
459: }
460: writer.write("</td>");
461: writer.write("<td>");
462: if (showRequest) {
463: writer.print(formatSize(mBeanServer.getAttribute(
464: pName, "requestBytesReceived"), false));
465: } else {
466: writer.write("?");
467: }
468: writer.write("</td>");
469: writer.write("<td>");
470: writer.print(filter(mBeanServer.getAttribute(pName,
471: "remoteAddr")));
472: writer.write("</td>");
473: writer.write("<td nowrap>");
474: writer.write(filter(mBeanServer.getAttribute(pName,
475: "virtualHost")));
476: writer.write("</td>");
477: writer.write("<td nowrap>");
478: if (showRequest) {
479: writer.write(filter(mBeanServer.getAttribute(pName,
480: "method")));
481: writer.write(" ");
482: writer.write(filter(mBeanServer.getAttribute(pName,
483: "currentUri")));
484: String queryString = (String) mBeanServer
485: .getAttribute(pName, "currentQueryString");
486: if ((queryString != null)
487: && (!queryString.equals(""))) {
488: writer.write("?");
489: writer.print(RequestUtil.filter(queryString));
490: }
491: writer.write(" ");
492: writer.write(filter(mBeanServer.getAttribute(pName,
493: "protocol")));
494: } else {
495: writer.write("?");
496: }
497: writer.write("</td>");
498: } else {
499: writer
500: .write("<td>?</td><td>?</td><td>?</td><td>?</td><td>?</td><td>?</td>");
501: }
502: } else if (mode == 1) {
503: writer.write("<worker ");
504: writer.write(" stage=\"" + stageStr + "\"");
505:
506: if (fullStatus) {
507: writer.write(" requestProcessingTime=\""
508: + mBeanServer.getAttribute(pName,
509: "requestProcessingTime") + "\"");
510: writer.write(" requestBytesSent=\"");
511: if (showRequest) {
512: writer.write(""
513: + mBeanServer.getAttribute(pName,
514: "requestBytesSent"));
515: } else {
516: writer.write("0");
517: }
518: writer.write("\"");
519: writer.write(" requestBytesReceived=\"");
520: if (showRequest) {
521: writer.write(""
522: + mBeanServer.getAttribute(pName,
523: "requestBytesReceived"));
524: } else {
525: writer.write("0");
526: }
527: writer.write("\"");
528: writer.write(" remoteAddr=\""
529: + filter(mBeanServer.getAttribute(pName,
530: "remoteAddr")) + "\"");
531: writer.write(" virtualHost=\""
532: + filter(mBeanServer.getAttribute(pName,
533: "virtualHost")) + "\"");
534:
535: if (showRequest) {
536: writer.write(" method=\""
537: + filter(mBeanServer.getAttribute(pName,
538: "method")) + "\"");
539: writer.write(" currentUri=\""
540: + filter(mBeanServer.getAttribute(pName,
541: "currentUri")) + "\"");
542:
543: String queryString = (String) mBeanServer
544: .getAttribute(pName, "currentQueryString");
545: if ((queryString != null)
546: && (!queryString.equals(""))) {
547: writer.write(" currentQueryString=\""
548: + RequestUtil.filter(queryString)
549: + "\"");
550: } else {
551: writer.write(" currentQueryString=\"?\"");
552: }
553: writer.write(" protocol=\""
554: + filter(mBeanServer.getAttribute(pName,
555: "protocol")) + "\"");
556: } else {
557: writer.write(" method=\"?\"");
558: writer.write(" currentUri=\"?\"");
559: writer.write(" currentQueryString=\"?\"");
560: writer.write(" protocol=\"?\"");
561: }
562: } else {
563: writer.write(" requestProcessingTime=\"0\"");
564: writer.write(" requestBytesSent=\"0\"");
565: writer.write(" requestBytesRecieved=\"0\"");
566: writer.write(" remoteAddr=\"?\"");
567: writer.write(" virtualHost=\"?\"");
568: writer.write(" method=\"?\"");
569: writer.write(" currentUri=\"?\"");
570: writer.write(" currentQueryString=\"?\"");
571: writer.write(" protocol=\"?\"");
572: }
573: writer.write(" />");
574: }
575:
576: }
577:
578: /**
579: * Write applications state.
580: */
581: public static void writeDetailedState(PrintWriter writer,
582: MBeanServer mBeanServer, int mode) throws Exception {
583:
584: if (mode == 0) {
585: ObjectName queryHosts = new ObjectName(
586: "*:j2eeType=WebModule,*");
587: Set hostsON = mBeanServer.queryNames(queryHosts, null);
588:
589: // Navigation menu
590: writer.print("<h1>");
591: writer.print("Application list");
592: writer.print("</h1>");
593:
594: writer.print("<p>");
595: int count = 0;
596: Iterator iterator = hostsON.iterator();
597: while (iterator.hasNext()) {
598: ObjectName contextON = (ObjectName) iterator.next();
599: String webModuleName = contextON.getKeyProperty("name");
600: if (webModuleName.startsWith("//")) {
601: webModuleName = webModuleName.substring(2);
602: }
603: int slash = webModuleName.indexOf("/");
604: if (slash == -1) {
605: count++;
606: continue;
607: }
608:
609: writer.print("<a href=\"#" + (count++) + ".0\">");
610: writer.print(webModuleName);
611: writer.print("</a>");
612: if (iterator.hasNext()) {
613: writer.print("<br>");
614: }
615:
616: }
617: writer.print("</p>");
618:
619: // Webapp list
620: count = 0;
621: iterator = hostsON.iterator();
622: while (iterator.hasNext()) {
623: ObjectName contextON = (ObjectName) iterator.next();
624: writer.print("<a class=\"A.name\" name=\"" + (count++)
625: + ".0\">");
626: writeContext(writer, contextON, mBeanServer, mode);
627: }
628:
629: } else if (mode == 1) {
630: // for now we don't write out the Detailed state in XML
631: }
632:
633: }
634:
635: /**
636: * Write context state.
637: */
638: protected static void writeContext(PrintWriter writer,
639: ObjectName objectName, MBeanServer mBeanServer, int mode)
640: throws Exception {
641:
642: if (mode == 0) {
643: String webModuleName = objectName.getKeyProperty("name");
644: String name = webModuleName;
645: if (name == null) {
646: return;
647: }
648:
649: String hostName = null;
650: String contextName = null;
651: if (name.startsWith("//")) {
652: name = name.substring(2);
653: }
654: int slash = name.indexOf("/");
655: if (slash != -1) {
656: hostName = name.substring(0, slash);
657: contextName = name.substring(slash);
658: } else {
659: return;
660: }
661:
662: ObjectName queryManager = new ObjectName(objectName
663: .getDomain()
664: + ":type=Manager,path="
665: + contextName
666: + ",host="
667: + hostName + ",*");
668: Set managersON = mBeanServer.queryNames(queryManager, null);
669: ObjectName managerON = null;
670: Iterator iterator2 = managersON.iterator();
671: while (iterator2.hasNext()) {
672: managerON = (ObjectName) iterator2.next();
673: }
674:
675: ObjectName queryJspMonitor = new ObjectName(objectName
676: .getDomain()
677: + ":type=JspMonitor,WebModule="
678: + webModuleName
679: + ",*");
680: Set jspMonitorONs = mBeanServer.queryNames(queryJspMonitor,
681: null);
682:
683: // Special case for the root context
684: if (contextName.equals("/")) {
685: contextName = "";
686: }
687:
688: writer.print("<h1>");
689: writer.print(name);
690: writer.print("</h1>");
691: writer.print("</a>");
692:
693: writer.print("<p>");
694: Object startTime = mBeanServer.getAttribute(objectName,
695: "startTime");
696: writer.print(" Start time: "
697: + new Date(((Long) startTime).longValue()));
698: writer.print(" Startup time: ");
699: writer.print(formatTime(mBeanServer.getAttribute(
700: objectName, "startupTime"), false));
701: writer.print(" TLD scan time: ");
702: writer.print(formatTime(mBeanServer.getAttribute(
703: objectName, "tldScanTime"), false));
704: if (managerON != null) {
705: writeManager(writer, managerON, mBeanServer, mode);
706: }
707: if (jspMonitorONs != null) {
708: writeJspMonitor(writer, jspMonitorONs, mBeanServer,
709: mode);
710: }
711: writer.print("</p>");
712:
713: String onStr = objectName.getDomain()
714: + ":j2eeType=Servlet,WebModule=" + webModuleName
715: + ",*";
716: ObjectName servletObjectName = new ObjectName(onStr);
717: Set set = mBeanServer.queryMBeans(servletObjectName, null);
718: Iterator iterator = set.iterator();
719: while (iterator.hasNext()) {
720: ObjectInstance oi = (ObjectInstance) iterator.next();
721: writeWrapper(writer, oi.getObjectName(), mBeanServer,
722: mode);
723: }
724:
725: } else if (mode == 1) {
726: // for now we don't write out the context in XML
727: }
728:
729: }
730:
731: /**
732: * Write detailed information about a manager.
733: */
734: public static void writeManager(PrintWriter writer,
735: ObjectName objectName, MBeanServer mBeanServer, int mode)
736: throws Exception {
737:
738: if (mode == 0) {
739: writer.print("<br>");
740: writer.print(" Active sessions: ");
741: writer.print(mBeanServer.getAttribute(objectName,
742: "activeSessions"));
743: writer.print(" Session count: ");
744: writer.print(mBeanServer.getAttribute(objectName,
745: "sessionCounter"));
746: writer.print(" Max active sessions: ");
747: writer.print(mBeanServer.getAttribute(objectName,
748: "maxActive"));
749: writer.print(" Rejected session creations: ");
750: writer.print(mBeanServer.getAttribute(objectName,
751: "rejectedSessions"));
752: writer.print(" Expired sessions: ");
753: writer.print(mBeanServer.getAttribute(objectName,
754: "expiredSessions"));
755: writer.print(" Longest session alive time: ");
756: writer.print(formatSeconds(mBeanServer.getAttribute(
757: objectName, "sessionMaxAliveTime")));
758: writer.print(" Average session alive time: ");
759: writer.print(formatSeconds(mBeanServer.getAttribute(
760: objectName, "sessionAverageAliveTime")));
761: writer.print(" Processing time: ");
762: writer.print(formatTime(mBeanServer.getAttribute(
763: objectName, "processingTime"), false));
764: } else if (mode == 1) {
765: // for now we don't write out the wrapper details
766: }
767:
768: }
769:
770: /**
771: * Write JSP monitoring information.
772: */
773: public static void writeJspMonitor(PrintWriter writer,
774: Set jspMonitorONs, MBeanServer mBeanServer, int mode)
775: throws Exception {
776:
777: int jspCount = 0;
778: int jspReloadCount = 0;
779:
780: Iterator iter = jspMonitorONs.iterator();
781: while (iter.hasNext()) {
782: ObjectName jspMonitorON = (ObjectName) iter.next();
783: Object obj = mBeanServer.getAttribute(jspMonitorON,
784: "jspCount");
785: jspCount += ((Integer) obj).intValue();
786: obj = mBeanServer.getAttribute(jspMonitorON,
787: "jspReloadCount");
788: jspReloadCount += ((Integer) obj).intValue();
789: }
790:
791: if (mode == 0) {
792: writer.print("<br>");
793: writer.print(" JSPs loaded: ");
794: writer.print(jspCount);
795: writer.print(" JSPs reloaded: ");
796: writer.print(jspReloadCount);
797: } else if (mode == 1) {
798: // for now we don't write out anything
799: }
800: }
801:
802: /**
803: * Write detailed information about a wrapper.
804: */
805: public static void writeWrapper(PrintWriter writer,
806: ObjectName objectName, MBeanServer mBeanServer, int mode)
807: throws Exception {
808:
809: if (mode == 0) {
810: String servletName = objectName.getKeyProperty("name");
811:
812: String[] mappings = (String[]) mBeanServer.invoke(
813: objectName, "findMappings", null, null);
814:
815: writer.print("<h2>");
816: writer.print(servletName);
817: if ((mappings != null) && (mappings.length > 0)) {
818: writer.print(" [ ");
819: for (int i = 0; i < mappings.length; i++) {
820: writer.print(mappings[i]);
821: if (i < mappings.length - 1) {
822: writer.print(" , ");
823: }
824: }
825: writer.print(" ] ");
826: }
827: writer.print("</h2>");
828:
829: writer.print("<p>");
830: writer.print(" Processing time: ");
831: writer.print(formatTime(mBeanServer.getAttribute(
832: objectName, "processingTime"), true));
833: writer.print(" Max time: ");
834: writer.print(formatTime(mBeanServer.getAttribute(
835: objectName, "maxTime"), false));
836: writer.print(" Request count: ");
837: writer.print(mBeanServer.getAttribute(objectName,
838: "requestCount"));
839: writer.print(" Error count: ");
840: writer.print(mBeanServer.getAttribute(objectName,
841: "errorCount"));
842: writer.print(" Load time: ");
843: writer.print(formatTime(mBeanServer.getAttribute(
844: objectName, "loadTime"), false));
845: writer.print(" Classloading time: ");
846: writer.print(formatTime(mBeanServer.getAttribute(
847: objectName, "classLoadTime"), false));
848: writer.print("</p>");
849: } else if (mode == 1) {
850: // for now we don't write out the wrapper details
851: }
852:
853: }
854:
855: /**
856: * Filter the specified message string for characters that are sensitive
857: * in HTML. This avoids potential attacks caused by including JavaScript
858: * codes in the request URL that is often reported in error messages.
859: *
860: * @param obj The message string to be filtered
861: */
862: public static String filter(Object obj) {
863:
864: if (obj == null)
865: return ("?");
866: String message = obj.toString();
867:
868: char content[] = new char[message.length()];
869: message.getChars(0, message.length(), content, 0);
870: StringBuffer result = new StringBuffer(content.length + 50);
871: for (int i = 0; i < content.length; i++) {
872: switch (content[i]) {
873: case '<':
874: result.append("<");
875: break;
876: case '>':
877: result.append(">");
878: break;
879: case '&':
880: result.append("&");
881: break;
882: case '"':
883: result.append(""");
884: break;
885: default:
886: result.append(content[i]);
887: }
888: }
889: return (result.toString());
890:
891: }
892:
893: /**
894: * Display the given size in bytes, either as KB or MB.
895: *
896: * @param mb true to display megabytes, false for kilobytes
897: */
898: public static String formatSize(Object obj, boolean mb) {
899:
900: long bytes = -1L;
901:
902: if (obj instanceof Long) {
903: bytes = ((Long) obj).longValue();
904: } else if (obj instanceof Integer) {
905: bytes = ((Integer) obj).intValue();
906: }
907:
908: if (mb) {
909: long mbytes = bytes / (1024 * 1024);
910: long rest = ((bytes - (mbytes * (1024 * 1024))) * 100)
911: / (1024 * 1024);
912: return (mbytes + "." + ((rest < 10) ? "0" : "") + rest + " MB");
913: } else {
914: return ((bytes / 1024) + " KB");
915: }
916:
917: }
918:
919: /**
920: * Display the given time in ms, either as ms or s.
921: *
922: * @param seconds true to display seconds, false for milliseconds
923: */
924: public static String formatTime(Object obj, boolean seconds) {
925:
926: long time = -1L;
927:
928: if (obj instanceof Long) {
929: time = ((Long) obj).longValue();
930: } else if (obj instanceof Integer) {
931: time = ((Integer) obj).intValue();
932: }
933:
934: if (seconds) {
935: return ((((float) time) / 1000) + " s");
936: } else {
937: return (time + " ms");
938: }
939: }
940:
941: /**
942: * Formats the given time (given in seconds) as a string.
943: *
944: * @param obj Time object to be formatted as string
945: *
946: * @return String formatted time
947: */
948: public static String formatSeconds(Object obj) {
949:
950: long time = -1L;
951:
952: if (obj instanceof Long) {
953: time = ((Long) obj).longValue();
954: } else if (obj instanceof Integer) {
955: time = ((Integer) obj).intValue();
956: }
957:
958: return (time + " s");
959: }
960:
961: }
|