001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.servlets;
031:
032: import com.caucho.config.ConfigException;
033: import com.caucho.jmx.Jmx;
034: import com.caucho.log.Log;
035: import com.caucho.management.server.*;
036: import com.caucho.util.L10N;
037: import com.caucho.util.QDate;
038:
039: import javax.management.MBeanServer;
040: import javax.management.ObjectName;
041: import javax.servlet.GenericServlet;
042: import javax.servlet.ServletException;
043: import javax.servlet.ServletRequest;
044: import javax.servlet.ServletResponse;
045: import javax.servlet.http.HttpServletRequest;
046: import javax.servlet.http.HttpServletResponse;
047: import java.io.IOException;
048: import java.io.PrintWriter;
049: import java.util.ArrayList;
050: import java.util.Collections;
051: import java.util.Comparator;
052: import java.util.Iterator;
053: import java.util.Set;
054: import java.util.logging.Level;
055: import java.util.logging.Logger;
056:
057: /**
058: * Displays some status information about the Resin server.
059: * The servlet must be explicitly enabled (using /servlet is forbidden),
060: * and it must have the init-param enable set to "read" or "write".
061: * (There will likely be a future additional requirement of satisfying
062: * a role.)
063: */
064: public class ResinStatusServlet extends GenericServlet {
065: static final protected Logger log = Log
066: .open(ResinStatusServlet.class);
067: static final L10N L = new L10N(ResinStatusServlet.class);
068:
069: private static final long SECOND = 1000L;
070: private static final long MINUTE = 60 * SECOND;
071: private static final long HOUR = 60 * MINUTE;
072: private static final long DAY = 24 * HOUR;
073:
074: private String _enable;
075:
076: private MBeanServer _mbeanServer;
077: private ResinMXBean _resin;
078: private ServerMXBean _server;
079: private ClusterMXBean _cluster;
080: private ProxyCacheMXBean _proxyCache;
081:
082: /**
083: * Set to read or write.
084: */
085: public void setEnable(String enable) throws ConfigException {
086: if ("read".equals(enable) || "write".equals(enable))
087: _enable = enable;
088: else
089: throw new ConfigException(L.l(
090: "enable value '{0}' must either be read or write.",
091: enable));
092: }
093:
094: /**
095: * Initialize the servlet with the server's sruns.
096: */
097: public void init() throws ServletException {
098: if (_enable == null)
099: throw new ServletException(
100: L
101: .l("ResinStatusServlet requires an explicit enable attribute."));
102:
103: try {
104: //_mbeanServer = (MBeanServer) new InitialContext().lookup("java:comp/jmx/GlobalMBeanServer");
105:
106: // _mbeanServer = Jmx.findMBeanServer();
107:
108: // _mbeanServer = Jmx.getMBeanServer();
109: _mbeanServer = Jmx.getGlobalMBeanServer();
110:
111: //_resinServer = (ResinServerMBean) Jmx.find("resin:type=ResinServer");
112: //_servletServer = (ServletServerMBean) Jmx.find("resin:name=default,type=Server");
113:
114: _resin = (ResinMXBean) Jmx.findGlobal("resin:type=Resin");
115: _server = (ServerMXBean) Jmx
116: .findGlobal("resin:type=Server");
117: _cluster = (ClusterMXBean) Jmx
118: .findGlobal("resin:type=Cluster");
119: _proxyCache = (ProxyCacheMXBean) Jmx
120: .findGlobal("resin:type=ProxyCache");
121: } catch (Exception e) {
122: throw new ServletException(e);
123: }
124: }
125:
126: /**
127: * Handle the request.
128: */
129: public void service(ServletRequest request, ServletResponse response)
130: throws IOException, ServletException {
131: try {
132: HttpServletRequest req = (HttpServletRequest) request;
133: HttpServletResponse res = (HttpServletResponse) response;
134:
135: res.setContentType("text/html");
136:
137: Thread thread = Thread.currentThread();
138: thread.setContextClassLoader(ClassLoader
139: .getSystemClassLoader());
140:
141: PrintWriter out = res.getWriter();
142:
143: printHeader(out);
144:
145: String hostName = req.getParameter("host");
146: String appName = req.getParameter("app");
147:
148: printServerHeader(out);
149: printPorts(out);
150: printSrun(out);
151: /*
152: printJNDI(out, _server.getJndiContext());
153: */
154: printApplicationSummary(out, req.getRequestURI());
155: printFooter(out);
156: } catch (IOException e) {
157: throw e;
158: } catch (ServletException e) {
159: throw e;
160: } catch (Exception e) {
161: throw new ServletException(e);
162: }
163: }
164:
165: /*
166: private void printApplication(PrintWriter out,
167: ApplicationAdmin app,
168: String pwd)
169: throws IOException, ServletException
170: {
171: ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
172:
173: try {
174: Thread.currentThread().setContextClassLoader(app.getClassLoader());
175:
176: printHeader(out);
177:
178: printApplicationHeader(out, app, pwd);
179: printJNDI(out, app.getJndiContext());
180:
181: printJMXServlets(out, app.getMBeanServer());
182:
183: printFooter(out);
184: } finally {
185: Thread.currentThread().setContextClassLoader(oldLoader);
186: }
187: }
188: */
189:
190: /**
191: * Prints generic server information.
192: */
193: public void printHeader(PrintWriter out) throws IOException,
194: ServletException {
195: }
196:
197: /**
198: * Prints server information.
199: */
200: public void printServerHeader(PrintWriter out) throws Exception {
201: out.println("<b>resin-status</b><br><br>");
202:
203: String id = _server.getId();
204:
205: out.println("<table border=\"0\">");
206: if (id != null)
207: out.println("<tr><td><b>Server:</b><td>" + id);
208:
209: String configFile = _resin.getConfigFile();
210: if (configFile != null)
211: out.println("<tr><td><b>Config:</b><td>" + configFile);
212:
213: long startTime = _server.getStartTime().getTime();
214:
215: out.println("<tr><td><b>Server Start:</b><td> "
216: + QDate.formatLocal(startTime));
217:
218: long totalMemory = _server.getRuntimeMemory();
219: out.println("<tr><td><b>Total Memory:</b><td> "
220: + (totalMemory / 1000000) + "."
221: + (totalMemory / 100000) % 10 + (totalMemory / 10000)
222: % 10 + "Meg");
223: long freeMemory = _server.getRuntimeMemoryFree();
224: out.println("<tr><td><b>Free Memory:</b><td> "
225: + (freeMemory / 1000000) + "." + (freeMemory / 100000)
226: % 10 + (freeMemory / 10000) % 10 + "Meg");
227:
228: long invocationHitCount = _server
229: .getInvocationCacheHitCountTotal();
230: long invocationMissCount = _server
231: .getInvocationCacheMissCountTotal();
232:
233: long totalCount = invocationHitCount + invocationMissCount;
234: if (totalCount == 0)
235: totalCount = 1;
236:
237: long hitRatio = (10000 * invocationHitCount) / totalCount;
238:
239: out.print("<tr><td><b>Invocation Hit Ratio:</b><td> "
240: + (hitRatio / 100) + "." + (hitRatio / 10) % 10
241: + (hitRatio) % 10 + "%");
242: out.println(" (" + invocationHitCount + "/" + totalCount + ")");
243:
244: if (_proxyCache != null) {
245: long proxyHitCount = _proxyCache.getHitCountTotal();
246: long proxyMissCount = _proxyCache.getMissCountTotal();
247:
248: totalCount = proxyHitCount + proxyMissCount;
249: if (totalCount == 0)
250: totalCount = 1;
251:
252: hitRatio = (10000 * proxyHitCount) / totalCount;
253:
254: out.print("<tr><td><b>Proxy Cache Hit Ratio:</b><td> "
255: + (hitRatio / 100) + "." + (hitRatio / 10) % 10
256: + (hitRatio) % 10 + "%");
257: out.println(" (" + proxyHitCount + "/" + totalCount + ")");
258: }
259:
260: out.println("</table>");
261:
262: printThreadHeader(out);
263: printConnectionPools(out, "");
264: }
265:
266: /**
267: * Prints thread information.
268: */
269: public void printThreadHeader(PrintWriter out) throws Exception {
270: out.println("<table border='3'>");
271:
272: ThreadPoolMXBean threadPool = (ThreadPoolMXBean) Jmx
273: .findGlobal("resin:type=ThreadPool");
274: out.println("<tr><th colspan='3'>Threads");
275: out.println(" <th colspan='3'>Config");
276: out.println("<tr><th>Active<th>Idle<th>Total");
277: out.println(" <th>thread-max<th>thread-idle-min");
278: out.println("<tr align='right'>");
279: out.println(" <td>" + threadPool.getThreadActiveCount());
280: out.println(" <td>" + threadPool.getThreadIdleCount());
281: out.println(" <td>" + threadPool.getThreadCount());
282:
283: out.println(" <td>" + threadPool.getThreadMax());
284: out.println(" <td>" + threadPool.getThreadIdleMin());
285:
286: out.println("</table>");
287: }
288:
289: /**
290: * Prints application information.
291: */
292: /*
293: public void printApplicationHeader(PrintWriter out,
294: ApplicationAdmin app,
295: String pwd)
296: throws IOException, ServletException
297: {
298: HostAdmin host = app.getHostAdmin();
299:
300: out.println("<b><a href=\"" + pwd + "\">resin-status</a> > ");
301: out.println("<a href=\"" + pwd +
302: "?host=" + host.getName() + "\">" + host.getURL() + "</a> > ");
303: out.println(app.getContextPath() + "</b><br><br>");
304:
305: String id = _server.getServerId();
306:
307: out.println("<table border=\"0\">");
308: if (id != null)
309: out.println("<tr><td><b>Server:</b><td>" + id);
310: Path config = _server.getConfig();
311: if (config != null)
312: out.println("<tr><td><b>Config:</b><td>" + config.getNativePath());
313:
314: out.println("<tr><td><b>Host:</b><td>" + app.getHostAdmin().getURL());
315: out.println("<tr><td><b>Web-App:</b><td>" + app.getContextPath());
316: out.println("<tr><td><b>App-Dir:</b><td>" + app.getAppDir().getNativePath());
317:
318: long startTime = _server.getStartTime();
319: long restartTime = app.getStartTime();
320:
321: out.println("<tr><td><b>Server Start:</b><td>" + QDate.formatLocal(startTime));
322: out.println("<tr><td><b>Web-App Start:</b><td> " + QDate.formatLocal(restartTime));
323: long totalMemory = Runtime.getRuntime().totalMemory();
324: out.println("<tr><td><b>Total Memory:</b><td> " +
325: (totalMemory / 1000000) + "." +
326: (totalMemory / 100000) % 10 +
327: (totalMemory / 10000) % 10 +
328: "Meg");
329: long freeMemory = Runtime.getRuntime().freeMemory();
330: out.println("<tr><td><b>Free Memory:</b><td> " +
331: (freeMemory / 1000000) + "." +
332: (freeMemory / 100000) % 10 +
333: (freeMemory / 10000) % 10 +
334: "Meg");
335:
336: out.println("<tr><td><b>Sessions:</b><td>" +
337: app.getActiveSessionCount());
338:
339: out.println("</table>");
340: }
341: */
342:
343: public void printPorts(PrintWriter out) throws IOException,
344: ServletException {
345: try {
346: PortMXBean[] portList = _server.getPorts();
347:
348: if (portList.length > 0) {
349: out.println("<h3>TCP ports</h3>");
350: out.println("<table border='2'>");
351: out
352: .println("<tr><th><th colspan='3'>Threads<th> ");
353: out.println("<tr><th>Protocol:Port");
354: out.println(" <th>Active<th>Idle<th>Total");
355: out.println(" <th>Keepalive<th>Select");
356:
357: for (int i = 0; i < portList.length; i++) {
358: PortMXBean port = portList[i];
359:
360: if (port == null
361: || !"active".equals(port.getState()))
362: continue;
363:
364: String host = port.getAddress();
365: if (host == null)
366: host = "*";
367:
368: out.print("<tr><td>");
369: out.print(port.getProtocolName() + "://" + host
370: + ":" + port.getPort());
371: out.println();
372:
373: out.print(" <td>" + port.getThreadActiveCount());
374: out.print("<td>" + port.getThreadIdleCount());
375: out.print("<td>" + port.getThreadActiveCount());
376: out.print("<td>" + port.getKeepaliveThreadCount());
377: out.print("<td>" + port.getKeepaliveSelectCount());
378: out.println();
379:
380: out.println();
381: }
382: out.println("</table>");
383: }
384: } catch (Exception e) {
385: throw new ServletException(e);
386: }
387: }
388:
389: public void printSrun(PrintWriter out) throws IOException,
390: ServletException {
391: try {
392: String[] clusterList = new String[0]; // _server.getClusterObjectNames();
393:
394: for (int i = 0; i < clusterList.length; i++) {
395: ClusterMXBean cluster = (ClusterMXBean) Jmx
396: .findGlobal(clusterList[i]);
397:
398: if (cluster == null) {
399: out.println("<h3>Cluster " + clusterList[i]
400: + " null</h3>");
401: continue;
402: }
403:
404: ObjectName objectName = cluster.getObjectName();
405:
406: String clusterName = objectName.getKeyProperty("name");
407:
408: out.println("<h3>Cluster " + clusterName + "</h3>");
409: out.println("<table border='2'>");
410: out.println("<tr><th>Host");
411: out.println(" <th>Active");
412:
413: ServerConnectorMXBean[] servers = cluster.getServers();
414:
415: for (int j = 0; j < servers.length; j++) {
416: ServerConnectorMXBean client = servers[j];
417:
418: String host = client.getAddress();
419: String port = String.valueOf(client.getPort());
420:
421: out.println("<tr>");
422:
423: boolean canConnect = client.ping();
424:
425: if (canConnect)
426: out.print("<td bgcolor='#80ff80'>");
427: else
428: out.print("<td>");
429:
430: out.print(host + ":" + port);
431:
432: if (canConnect)
433: out.println(" (up)");
434: else
435: out.println(" (down)");
436:
437: out.println("<td>"
438: + client.getConnectionActiveCount());
439: }
440:
441: out.println("</table>");
442: }
443: } catch (Exception e) {
444: throw new ServletException(e);
445: }
446: }
447:
448: public void printConnectionPools(PrintWriter out, String context)
449: throws Exception {
450: ObjectName pattern = new ObjectName(
451: "resin:*,type=ConnectionPool" + context);
452:
453: Set<ObjectName> poolNames;
454: poolNames = _mbeanServer.queryNames(pattern, null);
455:
456: if (poolNames.size() == 0)
457: return;
458:
459: out.println("<h3>Connection Pools</h3>");
460:
461: out.println("<table border='2'>");
462: out
463: .println("<tr><th> <th colspan='3'>Connections<th colspan='2'>Config");
464: out.println("<tr><th>Name<th>Active<th>Idle<th>Total");
465: out.println(" <th>max-connections<th>idle-time");
466:
467: Iterator<ObjectName> iter = poolNames.iterator();
468: while (iter.hasNext()) {
469: ObjectName name = iter.next();
470:
471: ConnectionPoolMXBean pool = (ConnectionPoolMXBean) Jmx
472: .findGlobal(name);
473:
474: if (pool != null) {
475: out.println("<tr><td>" + pool.getName());
476: out.println(" <td>"
477: + pool.getConnectionActiveCount());
478: out.println(" <td>" + pool.getConnectionIdleCount());
479: out.println(" <td>" + pool.getConnectionCount());
480:
481: out.println(" <td>" + pool.getMaxConnections());
482: out.println(" <td>"
483: + periodToString(pool.getMaxIdleTime()));
484: }
485: }
486:
487: out.println("</table>");
488: }
489:
490: private String periodToString(long time) {
491: if (time == 0)
492: return "0s";
493: else if (time % DAY == 0)
494: return (time / DAY) + "d";
495: else if (time % HOUR == 0)
496: return (time / HOUR) + "h";
497: else if (time % MINUTE == 0)
498: return (time / MINUTE) + "min";
499: else if (time % SECOND == 0)
500: return (time / SECOND) + "s";
501: else
502: return time + "ms";
503: }
504:
505: /*
506: public void printSrun(PrintWriter out)
507: throws IOException, ServletException
508: {
509: DistributionServer []srunList = _server.getDistributionServerList();
510:
511: if (srunList == null || srunList.length == 0)
512: return;
513:
514: out.println("<h3>Srun Servers</h3>");
515: out.println("<table border=2>");
516: out.println("<tr><th>Host</th><th>Active Count</th><th>live-time</th><th>dead-time</th><th>request-timeout</th>");
517:
518: for (int i = 0; i < srunList.length; i++) {
519: DistributionServer srun = srunList[i];
520: out.print("<tr>");
521:
522: boolean isLive = false;
523: try {
524: ReadWritePair pair = srun.open();
525: if (pair != null) {
526: isLive = true;
527: srun.free(pair);
528: }
529: } catch (Throwable e) {
530: dbg.log(e);
531: }
532:
533: if (isLive) {
534: out.println("<td bgcolor=\"#66ff66\">" +
535: (srun.getIndex() + 1) + ". " +
536: srun.getHost() + ":" + srun.getPort() +
537: (srun.isBackup() ? "*" : "") +
538: " (ok)");
539: }
540: else {
541: out.println("<td bgcolor=\"#ff6666\">" +
542: (srun.getIndex() + 1) + ". " +
543: srun.getHost() + ":" + srun.getPort() +
544: (srun.isBackup() ? "*" : "") +
545: " (down)");
546: }
547: out.println("<td>" + srun.getActiveCount());
548: out.println("<td>" + srun.getLiveTime() / 1000);
549: out.println("<td>" + srun.getDeadTime() / 1000);
550: out.println("<td>" + srun.getTimeout() / 1000);
551: }
552: out.println("</table>");
553: }
554:
555: public void printJNDI(PrintWriter out, Context ic)
556: throws IOException, ServletException
557: {
558: printDatabasePools(out, ic);
559: printEJBLocalHomes(out, ic);
560: printEJBRemoteHomes(out, ic);
561: }
562:
563: public void printEJBLocalHomes(PrintWriter out, Context ic)
564: throws IOException, ServletException
565: {
566: try {
567: Context cmpCxt = (Context) ic.lookup("java:comp/env/cmp");
568:
569: if (cmpCxt == null)
570: return;
571:
572: NamingEnumeration list = cmpCxt.list("");
573:
574: ArrayList cmpNames = new ArrayList();
575: while (list.hasMoreElements()) {
576: NameClassPair pair = (NameClassPair) list.nextElement();
577:
578: cmpNames.add(pair.getName());
579: }
580:
581: if (cmpNames.size() == 0)
582: return;
583:
584: out.println("<h3>EJB Local Home</h3>");
585:
586: out.println("<table border=\"2\">");
587: out.println("<tr><th>Name<th>Home Stub Class");
588:
589: Collections.sort(cmpNames);
590:
591: for (int i = 0; i < cmpNames.size(); i++) {
592: String name = (String) cmpNames.get(i);
593:
594: Object value = cmpCxt.lookup(name);
595: if (! (value instanceof EJBLocalHome))
596: continue;
597:
598: EJBLocalHome home = (EJBLocalHome) value;
599: out.print("<tr><td>cmp/" + name);
600: Class homeStub = home.getClass();
601: Class []interfaces = home.getClass().getInterfaces();
602: for (int j = 0; j < interfaces.length; j++) {
603: if (EJBLocalHome.class.isAssignableFrom(interfaces[j])) {
604: homeStub = interfaces[j];
605: break;
606: }
607: }
608: out.print("<td>" + homeStub.getName());
609: }
610: out.println("</table>");
611: } catch (Exception e) {
612: dbg.log(e);
613: }
614: }
615:
616: public void printEJBRemoteHomes(PrintWriter out, Context ic)
617: throws IOException, ServletException
618: {
619: try {
620: Context ejbCxt = (Context) ic.lookup("java:comp/env/ejb");
621:
622: if (ejbCxt == null)
623: return;
624:
625: NamingEnumeration list = ejbCxt.list("");
626:
627: ArrayList ejbNames = new ArrayList();
628: while (list.hasMoreElements()) {
629: NameClassPair pair = (NameClassPair) list.nextElement();
630:
631: ejbNames.add(pair.getName());
632: }
633:
634: if (ejbNames.size() == 0)
635: return;
636:
637: out.println("<h3>EJB Home</h3>");
638:
639: out.println("<table border=\"2\">");
640: out.println("<tr><th>Name<th>Home Stub Class");
641:
642: Collections.sort(ejbNames);
643:
644: for (int i = 0; i < ejbNames.size(); i++) {
645: String name = (String) ejbNames.get(i);
646:
647: Object value = ejbCxt.lookup(name);
648: if (! (value instanceof EJBHome))
649: continue;
650:
651: EJBHome home = (EJBHome) value;
652: out.print("<tr><td>ejb/" + name);
653: Class homeStub = home.getClass();
654: Class []interfaces = home.getClass().getInterfaces();
655: for (int j = 0; j < interfaces.length; j++) {
656: if (EJBHome.class.isAssignableFrom(interfaces[j])) {
657: homeStub = interfaces[j];
658: break;
659: }
660: }
661: out.print("<td>" + homeStub.getName());
662: }
663: out.println("</table>");
664: } catch (Exception e) {
665: dbg.log(e);
666: }
667: }
668:
669: public void printJMXServlets(PrintWriter out, MXBeanServer server)
670: throws IOException, ServletException
671: {
672: try {
673: ObjectName queryName = new ObjectName("*:j2eeType=Servlet,*");
674:
675: Set servlets = server.queryNames(queryName, null);
676:
677: if (servlets.size() == 0)
678: return;
679:
680: out.println("<h3>Servlets</h3>");
681:
682: Iterator iter = servlets.iterator();
683: while (iter.hasNext()) {
684: ObjectName servletName = (ObjectName) iter.next();
685:
686: String name = servletName.getKeyProperty("name");
687: MXBeanInfo mbeanInfo = server.getMXBeanInfo(servletName);
688: MXBeanAttributeInfo []attrs = mbeanInfo.getAttributes();
689:
690: out.println("<table border=\"2\">");
691: out.print("<tr><th>Name</th>");
692:
693: for (int i = 0; i < attrs.length; i++)
694: out.print("<th>" + attrs[i].getName() + "</th>");
695: out.println("</tr>");
696:
697: out.print("<tr><td>" + name + "</td>");
698: for (int i = 0; i < attrs.length; i++) {
699: Object value = server.getAttribute(servletName, attrs[i].getName());
700:
701: out.print("<td>" + value + "</td>");
702: }
703:
704: out.println("</table>");
705: }
706: } catch (Exception e) {
707: dbg.log(e);
708: }
709: }
710: */
711:
712: public void printApplicationSummary(PrintWriter out, String pwd)
713: throws Exception {
714: out.println("<h3>Hosts and Applications</h3>");
715:
716: out.println("<table border=\"2\">");
717: out.println("<tr><th>Host<th>Web-App<th>State<th>Sessions");
718:
719: ObjectName hostPattern = new ObjectName("resin:*,type=Host");
720:
721: Set<ObjectName> names = _mbeanServer.queryNames(hostPattern,
722: null);
723: Iterator<ObjectName> iter = names.iterator();
724:
725: ArrayList<HostMXBean> hosts = new ArrayList<HostMXBean>();
726:
727: while (iter.hasNext()) {
728: ObjectName name = iter.next();
729:
730: // the Host with name=current is a duplicate
731: if ("current".equals(name.getKeyProperty("name")))
732: continue;
733:
734: HostMXBean host = (HostMXBean) Jmx.findGlobal(name);
735:
736: if (host != null) {
737: hosts.add(host);
738: }
739: }
740:
741: Collections.sort(hosts, new HostCompare());
742:
743: for (int i = 0; i < hosts.size(); i++) {
744: HostMXBean host = hosts.get(i);
745:
746: out.println("<tr><td><b>" + host.getURL() + "</b>");
747:
748: // thread.setContextClassLoader(hostLoader);
749:
750: String hostName = host.getHostName();
751: if (hostName.equals(""))
752: hostName = "default";
753:
754: ObjectName appPattern = new ObjectName("resin:*,Host="
755: + hostName + ",type=WebApp");
756:
757: names = _mbeanServer.queryNames(appPattern, null);
758: iter = names.iterator();
759:
760: ArrayList<WebAppMXBean> apps = new ArrayList<WebAppMXBean>();
761:
762: while (iter.hasNext()) {
763: ObjectName name = iter.next();
764:
765: try {
766: WebAppMXBean app = (WebAppMXBean) Jmx
767: .findGlobal(name);
768:
769: if (app != null)
770: apps.add(app);
771: } catch (Exception e) {
772: log.log(Level.WARNING, e.toString());
773: out.println("<tr><td>" + name + "<td>"
774: + e.toString());
775: }
776: }
777:
778: Collections.sort(apps, new AppCompare());
779:
780: for (int j = 0; j < apps.size(); j++) {
781: WebAppMXBean app = apps.get(j);
782: SessionManagerMXBean session = app.getSessionManager();
783:
784: String contextPath = app.getContextPath();
785:
786: if (contextPath.equals(""))
787: contextPath = "/";
788:
789: out.print("<tr><td><td>");
790: out.print("<a href=\"" + pwd + "?host="
791: + host.getHostName() + "&app="
792: + app.getContextPath() + "\">");
793: out.print(contextPath);
794: out.print("</a>");
795:
796: String state = app.getState();
797: if (state.equals("active"))
798: out
799: .print("<td bgcolor='#80ff80'>"
800: + app.getState());
801: else
802: out.print("<td>" + app.getState());
803: out.print("<td>" + session.getSessionActiveCount());
804: }
805: }
806:
807: out.println("</table>");
808: }
809:
810: public void printVirtualHosts(PrintWriter out) throws IOException,
811: ServletException {
812: }
813:
814: /**
815: * Prints footer information.
816: */
817: public void printFooter(PrintWriter out) throws IOException,
818: ServletException {
819: /*
820: if (_server.isTesting())
821: out.println("<br><em>Resin test</em>");
822: else
823: */
824: out.println("<br><em>" + com.caucho.Version.FULL_VERSION
825: + "</em>");
826: }
827:
828: static class HostCompare implements Comparator<HostMXBean> {
829: public int compare(HostMXBean a, HostMXBean b) {
830: String urlA = a.getURL();
831: String urlB = b.getURL();
832:
833: if (urlA == urlB)
834: return 0;
835: else if (urlA == null)
836: return -1;
837: else if (urlB == null)
838: return 1;
839: else
840: return urlA.compareTo(urlB);
841: }
842: }
843:
844: static class AppCompare implements Comparator<WebAppMXBean> {
845: public int compare(WebAppMXBean a, WebAppMXBean b) {
846: String cpA = a.getContextPath();
847: String cpB = b.getContextPath();
848:
849: return cpA.compareTo(cpB);
850: }
851: }
852: }
|