remm 2003/09/04 07:22:18 Modified: webapps/manager/WEB-INF/classes/org/apache/catalina/manager Constants.java StatusManagerServlet.java Added: webapps/manager/WEB-INF/classes/org/apache/catalina/manager StatusTransformer.java Log: - Refactor the status servlet, allowing for XML output in addition to the user friendly HTML. - Submitted by Peter Lin, inspired by the code from John Turner which was originally rejected. Revision Changes Path 1.6 +9 -3 jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/Constants.java Index: Constants.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/Constants.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Constants.java 30 Jul 2003 18:43:01 -0000 1.5 +++ Constants.java 4 Sep 2003 14:22:18 -0000 1.6 @@ -238,5 +238,11 @@ "</body>\n" + "</html>"; + public static final String XML_DECLARATION = + "<?xml version=\"1.0\"?>"; + + public static final String XML_STYLE = + "<?xml-stylesheet type=\"text/xsl\" href=\"xform.xsl\" ?>"; + } 1.11 +33 -446 jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/StatusManagerServlet.java Index: StatusManagerServlet.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/StatusManagerServlet.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- StatusManagerServlet.java 17 Aug 2003 14:50:24 -0000 1.10 +++ StatusManagerServlet.java 4 Sep 2003 14:22:18 -0000 1.11 @@ -67,7 +67,6 @@ import java.io.IOException; import java.io.PrintWriter; -import java.text.MessageFormat; import java.util.Enumeration; import java.util.Iterator; import java.util.Set; @@ -81,15 +80,12 @@ import javax.management.ObjectName; import javax.servlet.ServletException; -import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.modeler.Registry; -import org.apache.tomcat.util.compat.JdkCompat; - import org.apache.catalina.util.ServerInfo; import org.apache.catalina.util.StringManager; @@ -247,7 +243,14 @@ HttpServletResponse response) throws IOException, ServletException { - response.setContentType("text/html"); + // mode is flag for HTML or XML output + int mode = 0; + // if ?XML=true, set the mode to XML + if (request.getParameter("XML") != null + && request.getParameter("XML").equals("true")) { + mode = 1; + } + StatusTransformer.setContentType(response, mode); PrintWriter writer = response.getWriter(); @@ -256,9 +259,8 @@ && (request.getPathInfo().equals("/all"))) { completeStatus = true; } - - // HTML Header Section - writer.print(Constants.HTML_HEADER_SECTION); + // use StatusTransformer to output status + StatusTransformer.writeHeader(writer,mode); // Body Header Section Object[] args = new Object[2]; @@ -268,8 +270,8 @@ } else { args[1] = sm.getString("statusServlet.title"); } - writer.print(MessageFormat.format - (Constants.BODY_HEADER_SECTION, args)); + // use StatusTransformer to output status + StatusTransformer.writeBody(writer,args,mode); // Manager Section args = new Object[9]; @@ -293,10 +295,11 @@ (request.getContextPath() + "/status/all"); args[8] = sm.getString("statusServlet.complete"); } - writer.print(MessageFormat.format(Constants.MANAGER_SECTION, args)); + // use StatusTransformer to output status + StatusTransformer.writeManager(writer,args,mode); // Server Header Section - args = new Object[7]; + args = new Object[7]; args[0] = sm.getString("htmlManagerServlet.serverTitle"); args[1] = sm.getString("htmlManagerServlet.serverVersion"); args[2] = sm.getString("htmlManagerServlet.serverJVMVersion"); @@ -304,8 +307,8 @@ args[4] = sm.getString("htmlManagerServlet.serverOSName"); args[5] = sm.getString("htmlManagerServlet.serverOSVersion"); args[6] = sm.getString("htmlManagerServlet.serverOSArch"); - writer.print(MessageFormat.format - (Constants.SERVER_HEADER_SECTION, args)); + // use StatusTransformer to output status + StatusTransformer.writePageHeading(writer,args,mode); // Server Row Section args = new Object[6]; @@ -315,455 +318,39 @@ args[3] = System.getProperty("os.name"); args[4] = System.getProperty("os.version"); args[5] = System.getProperty("os.arch"); - writer.print(MessageFormat.format(Constants.SERVER_ROW_SECTION, args)); + // use StatusTransformer to output status + StatusTransformer.writeServerInfo(writer,args,mode); try { // Display virtual machine statistics - writeVMState(writer); + // writeVMState(writer); + StatusTransformer.writeVMState(writer,mode); Enumeration enum = threadPools.elements(); while (enum.hasMoreElements()) { ObjectName objectName = (ObjectName) enum.nextElement(); String name = objectName.getKeyProperty("name"); - writeConnectorState(writer, objectName, name); + // use StatusTransformer to output status + StatusTransformer.writeConnectorState(writer,objectName, + name,mBeanServer,globalRequestProcessors, + requestProcessors,mode); } if ((request.getPathInfo() != null) && (request.getPathInfo().equals("/all"))) { // Warning: slow - writeDetailedState(writer); + // use StatusTransformer to output status + StatusTransformer.writeDetailedState(writer,mBeanServer,mode); } } catch (Exception e) { e.printStackTrace(); } - // HTML Tail Section - writer.print(Constants.HTML_TAIL_SECTION); - - } - - - /** - * Write virtual machine state. - */ - protected void writeVMState(PrintWriter writer) - throws Exception { - - writer.print("<h1>JVM</h1>"); - - writer.print("<p>"); - writer.print(" Free memory: "); - writer.print(formatSize(new Long(Runtime.getRuntime().freeMemory()), - true)); - writer.print(" Total memory: "); - writer.print(formatSize(new Long(Runtime.getRuntime().totalMemory()), - true)); - writer.print(" Max memory: "); - writer.print(formatSize - (new Long(JdkCompat.getJdkCompat().getMaxMemory()), - true)); - writer.print("</p>"); - - } - - - /** - * Write connector state. - */ - protected void writeConnectorState(PrintWriter writer, - ObjectName tpName, String name) - throws Exception { - - writer.print("<h1>"); - writer.print(name); - writer.print("</h1>"); - - writer.print("<p>"); - writer.print(" Max threads: "); - writer.print(mBeanServer.getAttribute(tpName, "maxThreads")); - writer.print(" Min spare threads: "); - writer.print(mBeanServer.getAttribute(tpName, "minSpareThreads")); - writer.print(" Max spare threads: "); - writer.print(mBeanServer.getAttribute(tpName, "maxSpareThreads")); - writer.print(" Current thread count: "); - writer.print(mBeanServer.getAttribute(tpName, "currentThreadCount")); - writer.print(" Current thread busy: "); - writer.print(mBeanServer.getAttribute(tpName, "currentThreadsBusy")); - - writer.print("<br/>"); - - ObjectName grpName = null; - - Enumeration enum = globalRequestProcessors.elements(); - while (enum.hasMoreElements()) { - ObjectName objectName = (ObjectName) enum.nextElement(); - if (name.equals(objectName.getKeyProperty("name"))) { - grpName = objectName; - } - } - - if (grpName == null) { - return; - } - - writer.print(" Max processing time: "); - writer.print(formatTime(mBeanServer.getAttribute - (grpName, "maxTime"), false)); - writer.print(" Processing time: "); - writer.print(formatTime(mBeanServer.getAttribute - (grpName, "processingTime"), true)); - writer.print(" Request count: "); - writer.print(mBeanServer.getAttribute(grpName, "requestCount")); - writer.print(" Error count: "); - writer.print(mBeanServer.getAttribute(grpName, "errorCount")); - writer.print(" Bytes received: "); - writer.print(formatSize(mBeanServer.getAttribute - (grpName, "bytesReceived"), true)); - writer.print(" Bytes sent: "); - writer.print(formatSize(mBeanServer.getAttribute - (grpName, "bytesSent"), true)); - writer.print("</p>"); - - writer.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>"); - - enum = requestProcessors.elements(); - while (enum.hasMoreElements()) { - ObjectName objectName = (ObjectName) enum.nextElement(); - if (name.equals(objectName.getKeyProperty("worker"))) { - writer.print("<tr>"); - writeProcessorState(writer, objectName); - writer.print("</tr>"); - } - } - - writer.print("</table>"); - - writer.print("<p>"); - writer.print("P: Parse and prepare request S: Service F: Finishing R: Ready K: Keepalive"); - writer.print("</p>"); - - } - - - /** - * Write processor state. - */ - protected void writeProcessorState(PrintWriter writer, ObjectName pName) - throws Exception { - - Integer stageValue = - (Integer) mBeanServer.getAttribute(pName, "stage"); - int stage = stageValue.intValue(); - boolean fullStatus = true; - boolean showRequest = true; - - writer.write("<td><strong>"); - - switch (stage) { - - case (1/*org.apache.coyote.Constants.STAGE_PARSE*/): - writer.write("P"); - fullStatus = false; - break; - case (2/*org.apache.coyote.Constants.STAGE_PREPARE*/): - writer.write("P"); - fullStatus = false; - break; - case (3/*org.apache.coyote.Constants.STAGE_SERVICE*/): - writer.write("S"); - break; - case (4/*org.apache.coyote.Constants.STAGE_ENDINPUT*/): - writer.write("F"); - break; - case (5/*org.apache.coyote.Constants.STAGE_ENDOUTPUT*/): - writer.write("F"); - break; - case (7/*org.apache.coyote.Constants.STAGE_ENDED*/): - writer.write("R"); - fullStatus = false; - break; - case (6/*org.apache.coyote.Constants.STAGE_KEEPALIVE*/): - writer.write("K"); - fullStatus = true; - showRequest = false; - break; - case (0/*org.apache.coyote.Constants.STAGE_NEW*/): - writer.write("R"); - fullStatus = false; - break; - default: - writer.write("?"); - fullStatus = false; - - } - - writer.write("</strong></td>"); - - if (fullStatus) { - writer.write("<td>"); - writer.print(formatTime(mBeanServer.getAttribute - (pName, "requestProcessingTime"), false)); - writer.write("</td>"); - writer.write("<td>"); - if (showRequest) { - writer.print(formatSize(mBeanServer.getAttribute - (pName, "requestBytesSent"), false)); - } else { - writer.write("?"); - } - writer.write("</td>"); - writer.write("<td>"); - if (showRequest) { - writer.print(formatSize(mBeanServer.getAttribute - (pName, "requestBytesReceived"), - false)); - } else { - writer.write("?"); - } - writer.write("</td>"); - writer.write("<td>"); - writer.print(filter(mBeanServer.getAttribute - (pName, "remoteAddr"))); - writer.write("</td>"); - writer.write("<td nowrap>"); - writer.write(filter(mBeanServer.getAttribute - (pName, "virtualHost"))); - writer.write("</td>"); - writer.write("<td nowrap>"); - if (showRequest) { - writer.write(filter(mBeanServer.getAttribute - (pName, "method"))); - writer.write(" "); - writer.write(filter(mBeanServer.getAttribute - (pName, "currentUri"))); - String queryString = (String) mBeanServer.getAttribute - (pName, "currentQueryString"); - if ((queryString != null) && (!queryString.equals(""))) { - writer.write("?"); - writer.print(queryString); - } - writer.write(" "); - writer.write(filter(mBeanServer.getAttribute - (pName, "protocol"))); - } else { - writer.write("?"); - } - writer.write("</td>"); - } else { - writer.write("<td>?</td><td>?</td><td>?</td><td>?</td><td>?</td><td>?</td>"); - } - + // use StatusTransformer to output status + StatusTransformer.writeFooter(writer,mode); } - - - /** - * Write applications state. - */ - protected void writeDetailedState(PrintWriter writer) - throws Exception { - - ObjectName queryHosts = new ObjectName("*:j2eeType=WebModule,*"); - Set hostsON = mBeanServer.queryNames(queryHosts, null); - Iterator iterator = hostsON.iterator(); - while (iterator.hasNext()) { - ObjectName contextON = (ObjectName) iterator.next(); - writeContext(writer, contextON); - } - - } - - - /** - * Write context state. - */ - protected void writeContext(PrintWriter writer, ObjectName objectName) - throws Exception { - - String webModuleName = objectName.getKeyProperty("name"); - String name = webModuleName; - if (name == null) { - return; - } - - String hostName = null; - String contextName = null; - if (name.startsWith("//")) { - name = name.substring(2); - } - int slash = name.indexOf("/"); - if (slash != -1) { - hostName = name.substring(0, slash); - contextName = name.substring(slash); - } else { - return; - } - // Special case for the root context - if (contextName.equals("/")) { - contextName = ""; - } - - writer.print("<h1>"); - writer.print(name); - writer.print("</h1>"); - - writer.print("<p>"); - writer.print(" Startup time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "startupTime"), false)); - writer.print(" TLD scan time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "tldScanTime"), false)); - writer.print("</p>"); - - String onStr = "*:j2eeType=Servlet,WebModule=" + webModuleName + ",*"; - ObjectName servletObjectName = new ObjectName(onStr); - Set set = mBeanServer.queryMBeans(servletObjectName, null); - Iterator iterator = set.iterator(); - while (iterator.hasNext()) { - ObjectInstance oi = (ObjectInstance) iterator.next(); - writeWrapper(writer, oi.getObjectName()); - } - - } - - - /** - * Write detailed information about a wrapper. - */ - public void writeWrapper(PrintWriter writer, ObjectName objectName) - throws Exception { - - String servletName = objectName.getKeyProperty("name"); - - String[] mappings = (String[]) - mBeanServer.invoke(objectName, "findMappings", null, null); - - writer.print("<h2>"); - writer.print(servletName); - if ((mappings != null) && (mappings.length > 0)) { - writer.print(" [ "); - for (int i = 0; i < mappings.length; i++) { - writer.print(mappings[i]); - if (i < mappings.length - 1) { - writer.print(" , "); - } - } - writer.print(" ] "); - } - writer.print("</h2>"); - - writer.print("<p>"); - writer.print(" Processing time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "processingTime"), true)); - writer.print(" Max time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "maxTime"), false)); - writer.print(" Request count: "); - writer.print(mBeanServer.getAttribute(objectName, "requestCount")); - writer.print(" Error count: "); - writer.print(mBeanServer.getAttribute(objectName, "errorCount")); - writer.print(" Load time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "loadTime"), false)); - writer.print(" Classloading time: "); - writer.print(formatTime(mBeanServer.getAttribute - (objectName, "classLoadTime"), false)); - writer.print("</p>"); - - } - - - /** - * Filter the specified message string for characters that are sensitive - * in HTML. This avoids potential attacks caused by including JavaScript - * codes in the request URL that is often reported in error messages. - * - * @param message The message string to be filtered - */ - public static String filter(Object obj) { - - if (obj == null) - return ("?"); - String message = obj.toString(); - - char content[] = new char[message.length()]; - message.getChars(0, message.length(), content, 0); - StringBuffer result = new StringBuffer(content.length + 50); - for (int i = 0; i < content.length; i++) { - switch (content[i]) { - case '<': - result.append("<"); - break; - case '>': - result.append(">"); - break; - case '&': - result.append("&"); - break; - case '"': - result.append("""); - break; - default: - result.append(content[i]); - } - } - return (result.toString()); - - } - - - /** - * Display the given size in bytes, either as KB or MB. - * - * @param mb true to display megabytes, false for kilobytes - */ - public static String formatSize(Object obj, boolean mb) { - - long bytes = -1L; - - if (obj instanceof Long) { - bytes = ((Long) obj).longValue(); - } else if (obj instanceof Integer) { - bytes = ((Integer) obj).intValue(); - } - - if (mb) { - long mbytes = bytes / 1000000; - long rest = (bytes / 10000) - mbytes * 100; - return (mbytes + "." + rest + " MB"); - } else { - return ((bytes / 1000) + " KB"); - } - - } - - - /** - * Display the given time in ms, either as ms or s. - * - * @param seconds true to display seconds, false for milliseconds - */ - public static String formatTime(Object obj, boolean seconds) { - - long time = -1L; - - if (obj instanceof Long) { - time = ((Long) obj).longValue(); - } else if (obj instanceof Integer) { - time = ((Integer) obj).intValue(); - } - - if (seconds) { - return ((time / 1000) + " s"); - } else { - return (time + " ms"); - } - - } - // ------------------------------------------- NotificationListener Methods 1.1 jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/StatusTransformer.java Index: StatusTransformer.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/StatusTransformer.java,v 1.1 2003/09/04 14:22:18 remm Exp $ * $Revision: 1.1 $ * $Date: 2003/09/04 14:22:18 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.manager; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.Enumeration; import java.util.Iterator; import java.util.Set; import java.util.Vector; import javax.servlet.http.HttpServletResponse; import org.apache.tomcat.util.compat.JdkCompat; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; /** * This is a refactoring of the servlet to externalize * the output into a simple class. Although we could * use XSLT, that is unnecessarily complex. * * @author Peter Lin * @version $Revision: 1.1 $ $Date: 2003/09/04 14:22:18 $ */ public class StatusTransformer { // --------------------------------------------------------- Public Methods public static void setContentType(HttpServletResponse response, int mode) { if (mode == 0){ response.setContentType("text/html"); } else if (mode == 1){ response.setContentType("text/xml"); } } /** * Process a GET request for the specified resource. * * @param request The servlet request we are processing * @param response The servlet response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet-specified error occurs */ public static void writeHeader(PrintWriter writer, int mode) { if (mode == 0){ // HTML Header Section writer.print(Constants.HTML_HEADER_SECTION); } else if (mode == 1){ writer.write(Constants.XML_DECLARATION); writer.write (Constants.XML_STYLE); writer.write("<status>"); } } /** * Write the header body. XML output doesn't bother * to output this stuff, since it's just title. * * @param PrintWriter writer * @param Object[] args * @param int mode */ public static void writeBody(PrintWriter writer, Object[] args, int mode) { if (mode == 0){ writer.print(MessageFormat.format (Constants.BODY_HEADER_SECTION, args)); } } /** * Write the manager webapp information. * * @param PrintWriter writer * @param Object[] args * @param int mode */ public static void writeManager(PrintWriter writer, Object[] args, int mode) { if (mode == 0){ writer.print(MessageFormat.format(Constants.MANAGER_SECTION, args)); } } public static void writePageHeading(PrintWriter writer, Object[] args, int mode) { if (mode == 0){ writer.print(MessageFormat.format (Constants.SERVER_HEADER_SECTION, args)); } } public static void writeServerInfo(PrintWriter writer, Object[] args, int mode){ if (mode == 0){ writer.print(MessageFormat.format(Constants.SERVER_ROW_SECTION, args)); } } /** * */ public static void writeFooter(PrintWriter writer, int mode) { if (mode == 0){ // HTML Tail Section writer.print(Constants.HTML_TAIL_SECTION); } else if (mode == 1){ writer.write("</status>"); } } /** * Write the VM state. Mode 0 will generate HTML. * Mode 1 will generate XML. */ protected static void writeVMState(PrintWriter writer, int mode) throws Exception { if (mode == 0){ writer.print("<h1>JVM</h1>"); writer.print("<p>"); writer.print(" Free memory: "); writer.print(formatSize (new Long(Runtime.getRuntime().freeMemory()), true)); writer.print(" Total memory: "); writer.print(formatSize (new Long(Runtime.getRuntime().totalMemory()), true)); writer.print(" Max memory: "); writer.print(formatSize (new Long(JdkCompat.getJdkCompat().getMaxMemory()), true)); writer.print("</p>"); } else if (mode == 1){ writer.write("<jvm>"); writer.write("<memory"); writer.write(" free='" + Runtime.getRuntime().freeMemory() + "'"); writer.write(" total='" + Runtime.getRuntime().totalMemory() + "'"); writer.write(" max='" + Runtime.getRuntime().maxMemory() + "'/>"); writer.write("</jvm>"); } } /** * Write connector state. */ protected static void writeConnectorState(PrintWriter writer, ObjectName tpName, String name, MBeanServer mBeanServer, Vector globalRequestProcessors, Vector requestProcessors, int mode) throws Exception { if (mode == 0){ writer.print("<h1>"); writer.print(name); writer.print("</h1>"); writer.print("<p>"); writer.print(" Max threads: "); writer.print(mBeanServer.getAttribute(tpName, "maxThreads")); writer.print(" Min spare threads: "); writer.print(mBeanServer.getAttribute(tpName, "minSpareThreads")); writer.print(" Max spare threads: "); writer.print(mBeanServer.getAttribute(tpName, "maxSpareThreads")); writer.print(" Current thread count: "); writer.print(mBeanServer.getAttribute(tpName, "currentThreadCount")); writer.print(" Current thread busy: "); writer.print(mBeanServer.getAttribute(tpName, "currentThreadsBusy")); writer.print("<br/>"); ObjectName grpName = null; Enumeration enum = globalRequestProcessors.elements(); while (enum.hasMoreElements()) { ObjectName objectName = (ObjectName) enum.nextElement(); if (name.equals(objectName.getKeyProperty("name"))) { grpName = objectName; } } if (grpName == null) { return; } writer.print(" Max processing time: "); writer.print(formatTime(mBeanServer.getAttribute (grpName, "maxTime"), false)); writer.print(" Processing time: "); writer.print(formatTime(mBeanServer.getAttribute (grpName, "processingTime"), true)); writer.print(" Request count: "); writer.print(mBeanServer.getAttribute(grpName, "requestCount")); writer.print(" Error count: "); writer.print(mBeanServer.getAttribute(grpName, "errorCount")); writer.print(" Bytes received: "); writer.print(formatSize(mBeanServer.getAttribute (grpName, "bytesReceived"), true)); writer.print(" Bytes sent: "); writer.print(formatSize(mBeanServer.getAttribute (grpName, "bytesSent"), true)); writer.print("</p>"); writer.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>"); enum = requestProcessors.elements(); while (enum.hasMoreElements()) { ObjectName objectName = (ObjectName) enum.nextElement(); if (name.equals(objectName.getKeyProperty("worker"))) { writer.print("<tr>"); writeProcessorState(writer, objectName, mBeanServer, mode); writer.print("</tr>"); } } writer.print("</table>"); writer.print("<p>"); writer.print("P: Parse and prepare request S: Service F: Finishing R: Ready K: Keepalive"); writer.print("</p>"); } else if (mode == 1){ writer.write("<connector name='" + name + "'>"); writer.write("<threadInfo "); writer.write(" maxThreads=\"" + mBeanServer.getAttribute(tpName, "maxThreads") + "\""); writer.write(" minSpareThreads=\"" + mBeanServer.getAttribute(tpName, "minSpareThreads") + "\""); writer.write(" maxSpareThreads=\"" + mBeanServer.getAttribute(tpName, "maxSpareThreads") + "\""); writer.write(" currentThreadCount=\"" + mBeanServer.getAttribute(tpName, "currentThreadCount") + "\""); writer.write(" currentThreadsBusy=\"" + mBeanServer.getAttribute(tpName, "currentThreadsBusy") + "\""); writer.write(" />"); ObjectName grpName = null; Enumeration enum = globalRequestProcessors.elements(); while (enum.hasMoreElements()) { ObjectName objectName = (ObjectName) enum.nextElement(); if (name.equals(objectName.getKeyProperty("name"))) { grpName = objectName; } } if (grpName != null) { writer.write("<requestInfo "); writer.write(" maxTime=\"" + mBeanServer.getAttribute(grpName, "maxTime") + "\""); writer.write(" processingTime=\"" + mBeanServer.getAttribute(grpName, "processingTime") + "\""); writer.write(" requestCount=\"" + mBeanServer.getAttribute(grpName, "requestCount") + "\""); writer.write(" errorCount=\"" + mBeanServer.getAttribute(grpName, "errorCount") + "\""); writer.write(" bytesReceived=\"" + mBeanServer.getAttribute(grpName, "bytesReceived") + "\""); writer.write(" bytesSent=\"" + mBeanServer.getAttribute(grpName, "bytesSent") + "\""); writer.write(" />"); writer.write("<workers>"); enum = requestProcessors.elements(); while (enum.hasMoreElements()) { ObjectName objectName = (ObjectName) enum.nextElement(); if (name.equals(objectName.getKeyProperty("worker"))) { writer.write("<worker>"); writeProcessorState(writer, objectName, mBeanServer, mode); writer.write("</worker>"); } } writer.write("</workers>"); } writer.write("</connector>"); } } /** * Write processor state. */ protected static void writeProcessorState(PrintWriter writer, ObjectName pName, MBeanServer mBeanServer, int mode) throws Exception { if (mode == 0) { Integer stageValue = (Integer) mBeanServer.getAttribute(pName, "stage"); int stage = stageValue.intValue(); boolean fullStatus = true; boolean showRequest = true; writer.write("<td><strong>"); switch (stage) { case (1/*org.apache.coyote.Constants.STAGE_PARSE*/): writer.write("P"); fullStatus = false; break; case (2/*org.apache.coyote.Constants.STAGE_PREPARE*/): writer.write("P"); fullStatus = false; break; case (3/*org.apache.coyote.Constants.STAGE_SERVICE*/): writer.write("S"); break; case (4/*org.apache.coyote.Constants.STAGE_ENDINPUT*/): writer.write("F"); break; case (5/*org.apache.coyote.Constants.STAGE_ENDOUTPUT*/): writer.write("F"); break; case (7/*org.apache.coyote.Constants.STAGE_ENDED*/): writer.write("R"); fullStatus = false; break; case (6/*org.apache.coyote.Constants.STAGE_KEEPALIVE*/): writer.write("K"); fullStatus = true; showRequest = false; break; case (0/*org.apache.coyote.Constants.STAGE_NEW*/): writer.write("R"); fullStatus = false; break; default: writer.write("?"); fullStatus = false; } writer.write("</strong></td>"); if (fullStatus) { writer.write("<td>"); writer.print(formatTime(mBeanServer.getAttribute (pName, "requestProcessingTime"), false)); writer.write("</td>"); writer.write("<td>"); if (showRequest) { writer.print(formatSize(mBeanServer.getAttribute (pName, "requestBytesSent"), false)); } else { writer.write("?"); } writer.write("</td>"); writer.write("<td>"); if (showRequest) { writer.print(formatSize(mBeanServer.getAttribute (pName, "requestBytesReceived"), false)); } else { writer.write("?"); } writer.write("</td>"); writer.write("<td>"); writer.print(filter(mBeanServer.getAttribute (pName, "remoteAddr"))); writer.write("</td>"); writer.write("<td nowrap>"); writer.write(filter(mBeanServer.getAttribute (pName, "virtualHost"))); writer.write("</td>"); writer.write("<td nowrap>"); if (showRequest) { writer.write(filter(mBeanServer.getAttribute (pName, "method"))); writer.write(" "); writer.write(filter(mBeanServer.getAttribute (pName, "currentUri"))); String queryString = (String) mBeanServer.getAttribute (pName, "currentQueryString"); if ((queryString != null) && (!queryString.equals(""))) { writer.write("?"); writer.print(queryString); } writer.write(" "); writer.write(filter(mBeanServer.getAttribute (pName, "protocol"))); } else { writer.write("?"); } writer.write("</td>"); } else { writer.write("<td>?</td><td>?</td><td>?</td><td>?</td><td>?</td><td>?</td>"); } } else if (mode == 1){ // for now we don't generate XML output } } /** * Write applications state. */ protected static void writeDetailedState(PrintWriter writer, MBeanServer mBeanServer, int mode) throws Exception { if (mode == 0){ ObjectName queryHosts = new ObjectName("*:j2eeType=WebModule,*"); Set hostsON = mBeanServer.queryNames(queryHosts, null); Iterator iterator = hostsON.iterator(); while (iterator.hasNext()) { ObjectName contextON = (ObjectName) iterator.next(); writeContext(writer, contextON, mBeanServer, mode); } } else if (mode == 1){ // for now we don't write out the Detailed state in XML } } /** * Write context state. */ protected static void writeContext(PrintWriter writer, ObjectName objectName, MBeanServer mBeanServer, int mode) throws Exception { if (mode == 0){ String webModuleName = objectName.getKeyProperty("name"); String name = webModuleName; if (name == null) { return; } String hostName = null; String contextName = null; if (name.startsWith("//")) { name = name.substring(2); } int slash = name.indexOf("/"); if (slash != -1) { hostName = name.substring(0, slash); contextName = name.substring(slash); } else { return; } // Special case for the root context if (contextName.equals("/")) { contextName = ""; } writer.print("<h1>"); writer.print(name); writer.print("</h1>"); writer.print("<p>"); writer.print(" Startup time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "startupTime"), false)); writer.print(" TLD scan time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "tldScanTime"), false)); writer.print("</p>"); String onStr = "*:j2eeType=Servlet,WebModule=" + webModuleName + ",*"; ObjectName servletObjectName = new ObjectName(onStr); Set set = mBeanServer.queryMBeans(servletObjectName, null); Iterator iterator = set.iterator(); while (iterator.hasNext()) { ObjectInstance oi = (ObjectInstance) iterator.next(); writeWrapper(writer, oi.getObjectName(), mBeanServer, mode); } } else if (mode == 1){ // for now we don't write out the context in XML } } /** * Write detailed information about a wrapper. */ public static void writeWrapper(PrintWriter writer, ObjectName objectName, MBeanServer mBeanServer, int mode) throws Exception { if (mode == 0){ String servletName = objectName.getKeyProperty("name"); String[] mappings = (String[]) mBeanServer.invoke(objectName, "findMappings", null, null); writer.print("<h2>"); writer.print(servletName); if ((mappings != null) && (mappings.length > 0)) { writer.print(" [ "); for (int i = 0; i < mappings.length; i++) { writer.print(mappings[i]); if (i < mappings.length - 1) { writer.print(" , "); } } writer.print(" ] "); } writer.print("</h2>"); writer.print("<p>"); writer.print(" Processing time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "processingTime"), true)); writer.print(" Max time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "maxTime"), false)); writer.print(" Request count: "); writer.print(mBeanServer.getAttribute(objectName, "requestCount")); writer.print(" Error count: "); writer.print(mBeanServer.getAttribute(objectName, "errorCount")); writer.print(" Load time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "loadTime"), false)); writer.print(" Classloading time: "); writer.print(formatTime(mBeanServer.getAttribute (objectName, "classLoadTime"), false)); writer.print("</p>"); } else if (mode == 1){ // for now we don't write out the wrapper details } } /** * Filter the specified message string for characters that are sensitive * in HTML. This avoids potential attacks caused by including JavaScript * codes in the request URL that is often reported in error messages. * * @param message The message string to be filtered */ public static String filter(Object obj) { if (obj == null) return ("?"); String message = obj.toString(); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuffer result = new StringBuffer(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } /** * Display the given size in bytes, either as KB or MB. * * @param mb true to display megabytes, false for kilobytes */ public static String formatSize(Object obj, boolean mb) { long bytes = -1L; if (obj instanceof Long) { bytes = ((Long) obj).longValue(); } else if (obj instanceof Integer) { bytes = ((Integer) obj).intValue(); } if (mb) { long mbytes = bytes / 1000000; long rest = (bytes / 10000) - mbytes * 100; return (mbytes + "." + rest + " MB"); } else { return ((bytes / 1000) + " KB"); } } /** * Display the given time in ms, either as ms or s. * * @param seconds true to display seconds, false for milliseconds */ public static String formatTime(Object obj, boolean seconds) { long time = -1L; if (obj instanceof Long) { time = ((Long) obj).longValue(); } else if (obj instanceof Integer) { time = ((Integer) obj).intValue(); } if (seconds) { return ((time / 1000) + " s"); } else { return (time + " ms"); } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]