[Jboss-cvs] JBossAS SVN: r56514 - branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Sep 1 19:58:39 EDT 2006
Author: scott.stark at jboss.org
Date: 2006-09-01 19:58:37 -0400 (Fri, 01 Sep 2006)
New Revision: 56514
Added:
branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfoMBean.java
Modified:
branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfo.java
Log:
Implement the ServerInfo.listThreadDump/listThreadCpu ops based on the java5 mxbeans
Modified: branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfo.java
===================================================================
--- branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfo.java 2006-09-01 22:29:13 UTC (rev 56513)
+++ branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfo.java 2006-09-01 23:58:37 UTC (rev 56514)
@@ -9,41 +9,44 @@
package org.jboss.system.server;
+import java.lang.reflect.Method;
+import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
-import java.lang.reflect.Method;
-
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
import javax.management.ObjectName;
-import javax.management.MBeanServer;
-import javax.management.MBeanRegistration;
import org.jboss.logging.Logger;
-import org.jboss.mx.util.ObjectNameFactory;
-import org.jboss.mx.server.ServerConstants;
-
import org.jboss.util.platform.Java;
/**
* An MBean that provides a rich view of system information for the JBoss
* server in which it is deployed.
*
- * @jmx:mbean name="jboss.system:type=ServerInfo"
- *
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Öberg</a>
+ * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Oberg</a>
* @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
* @author <a href="mailto:hiram.chirino at jboss.org">Hiram Chirino</a>
* @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
* @author <a href="mailto:marc.fleury at jboss.org">Marc Fleury</a>
+ * @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
* @version $Revision$
*/
public class ServerInfo
implements ServerInfoMBean, MBeanRegistration
{
- public static final ObjectName DEFAULT_LOADER_REPOSITORY = ObjectNameFactory.create(ServerConstants.DEFAULT_LOADER_NAME);
-
/** Class logger. */
private static final Logger log = Logger.getLogger(ServerInfo.class);
+
+ /** Zero */
+ private static final Integer ZERO = new Integer(0);
+
+ /** The MBeanServer we are registered to */
+ private MBeanServer server;
/** The cached host name for the server. */
private String hostName;
@@ -51,9 +54,38 @@
/** The cached host address for the server. */
private String hostAddress;
- private MBeanServer server;
+ /** The cached jdk5+ ThreadMXBean instance */
+ private Object threadMXBean;
+ /** The cached jdk5+ ManagementFactory.getMemoryPoolMXBeans() method */
+ private Method getMemoryPoolMXBeans;
+ /** The cached jdk5+ MemoryPoolMXBean methods */
+ private Method getName;
+ private Method getType;
+ private Method getUsage;
+ private Method getPeakUsage;
+
+ /** The cached jdk5+ MemoryUsage methods */
+ private Method getInit;
+ private Method getUsed;
+ private Method getCommitted;
+ private Method getMax;
+
+ /** The cached jdk5+ ThreadMXBean.getThreadInfo() method */
+ private Method getThreadInfo;
+ private Method getAllThreadIds;
+ private Method getThreadCpuTime;
+
+ /** The cached jdk5+ ThreadInfo methods */
+ private Method getThreadName;
+ private Method getThreadState;
+ private Method getLockName;
+ private Method getStackTrace;
+
+ /** The cached jdk5+ Thread.getId() method */
+ private Method getThreadId;
+
///////////////////////////////////////////////////////////////////////////
// JMX Hooks //
///////////////////////////////////////////////////////////////////////////
@@ -77,18 +109,65 @@
System.getProperty("os.version") + "," +
System.getProperty("os.arch"));
- // Dump out the entire system properties if debug is enabled
- if (log.isDebugEnabled())
+ // Dump out the entire system properties
+ log.debug("Full System Properties Dump");
+ Enumeration names = System.getProperties().propertyNames();
+ while (names.hasMoreElements())
{
- log.debug("Full System Properties Dump");
- Enumeration names = System.getProperties().propertyNames();
- while (names.hasMoreElements())
- {
- String pname = (String)names.nextElement();
+ String pname = (String)names.nextElement();
log.debug(" " + pname + ": " + System.getProperty(pname));
- }
}
+ // cache a reference to the platform ThreadMXBean
+ // and related Thread/ThreadInfo methods, if available
+ try
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ Class clazz = cl.loadClass("java.lang.management.ManagementFactory");
+
+ // cache ThreadMXBean instance
+ Method method = clazz.getMethod("getThreadMXBean", null);
+ this.threadMXBean = method.invoke(null, null);
+
+ // cache ManagementFactory.getMemoryPoolMXBeans() method
+ this.getMemoryPoolMXBeans = clazz.getMethod("getMemoryPoolMXBeans", null);
+
+ // cache MemoryPoolMXBean methods
+ clazz = cl.loadClass("java.lang.management.MemoryPoolMXBean");
+ this.getName = clazz.getMethod("getName", null);
+ this.getType = clazz.getMethod("getType", null);
+ this.getUsage = clazz.getMethod("getUsage", null);
+ this.getPeakUsage = clazz.getMethod("getPeakUsage", null);
+
+ // cache MemoryUsage methods
+ clazz = cl.loadClass("java.lang.management.MemoryUsage");
+ this.getInit = clazz.getMethod("getInit", null);
+ this.getUsed = clazz.getMethod("getUsed", null);
+ this.getCommitted = clazz.getMethod("getCommitted", null);
+ this.getMax = clazz.getMethod("getMax", null);
+
+ // cache ThreadMXBean.getThreadInfo() method
+ clazz = cl.loadClass("java.lang.management.ThreadMXBean");
+ this.getThreadInfo = clazz.getMethod("getThreadInfo", new Class[] { Long.TYPE, Integer.TYPE } );
+ this.getAllThreadIds = clazz.getMethod("getAllThreadIds", null );
+ this.getThreadCpuTime = clazz.getMethod("getThreadCpuTime", new Class[] { Long.TYPE } );
+
+ // cache ThreadInfo methods
+ clazz = cl.loadClass("java.lang.management.ThreadInfo");
+ this.getThreadName = clazz.getMethod("getThreadName", null);
+ this.getThreadState = clazz.getMethod("getThreadState", null);
+ this.getLockName = clazz.getMethod("getLockName", null);
+ this.getStackTrace = clazz.getMethod("getStackTrace", null);
+
+ // cache Thread.getId() method
+ clazz = Thread.class;
+ this.getThreadId = clazz.getMethod("getId", null);
+ }
+ catch (Exception e)
+ {
+ log.debug("Cannot access platform ThreadMXBean", e);
+ }
+
return name == null ? OBJECT_NAME : name;
}
@@ -290,17 +369,90 @@
return hostAddress;
}
- private ThreadGroup getRootThreadGroup()
+ /**
+ * Return a listing of the thread pools on jdk5+.
+ *
+ * @jmx:managed-operation
+ *
+ * @param fancy produce a text-based graph when true
+ */
+ public String listMemoryPools(boolean fancy)
{
- ThreadGroup group = Thread.currentThread().getThreadGroup();
- while (group.getParent() != null)
+ if (getMemoryPoolMXBeans != null)
{
- group = group.getParent();
+ // running under jdk5+
+ StringBuffer sbuf = new StringBuffer(4196);
+ try
+ {
+ // get the pools
+ List poolList = (List)getMemoryPoolMXBeans.invoke(null, null);
+ sbuf.append("<b>Total Memory Pools:</b> ").append(poolList.size());
+ sbuf.append("<blockquote>");
+ for (Iterator i = poolList.iterator(); i.hasNext(); )
+ {
+ // MemoryPoolMXBean instance
+ Object pool = i.next();
+ String name = (String)getName.invoke(pool, null);
+ // enum MemoryType
+ Object type = getType.invoke(pool, null);
+ sbuf.append("<b>Pool: ").append(name);
+ sbuf.append("</b> (").append(type).append(")");
+
+ // PeakUsage/CurrentUsage
+ Object peakUsage = getPeakUsage.invoke(pool, null);
+ Object usage = getUsage.invoke(pool, null);
+
+ sbuf.append("<blockquote>");
+ if (usage != null && peakUsage != null)
+ {
+ Long init = (Long)getInit.invoke(peakUsage, null);
+ Long used = (Long)getUsed.invoke(peakUsage, null);
+ Long committed = (Long)getCommitted.invoke(peakUsage, null);
+ Long max = (Long)getMax.invoke(peakUsage, null);
+
+ sbuf.append("Peak Usage : ");
+ sbuf.append("init:").append(init);
+ sbuf.append(", used:").append(used);
+ sbuf.append(", committed:").append(committed);
+ sbuf.append(", max:").append(max);
+ sbuf.append("<br>");
+
+ init = (Long)getInit.invoke(usage, null);
+ used = (Long)getUsed.invoke(usage, null);
+ committed = (Long)getCommitted.invoke(usage, null);
+ max = (Long)getMax.invoke(usage, null);
+
+ sbuf.append("Current Usage : ");
+ sbuf.append("init:").append(init);
+ sbuf.append(", used:").append(used);
+ sbuf.append(", committed:").append(committed);
+ sbuf.append(", max:").append(max);
+
+ if (fancy)
+ {
+ TextGraphHelper.poolUsage(sbuf, used.longValue(), committed.longValue(), max.longValue());
+ }
+ }
+ else
+ {
+ sbuf.append("Memory pool NOT valid!");
+ }
+ sbuf.append("</blockquote><br>");
+ }
+ sbuf.append("</blockquote>");
+ }
+ catch (Exception e)
+ {
+ // ignore
+ }
+ return sbuf.toString();
}
-
- return group;
+ else
+ {
+ return "<b>Memory pool information available only under a JDK5+ compatible JVM!</b>";
+ }
}
-
+
/**
* @jmx:managed-operation
*/
@@ -326,28 +478,115 @@
{
ThreadGroup root = getRootThreadGroup();
- // I'm not sure why what gets reported is off by +1,
- // but I'm adjusting so that it is consistent with the display
- int activeThreads = root.activeCount()-1;
- // I'm not sure why what gets reported is off by -1
- // but I'm adjusting so that it is consistent with the display
- int activeGroups = root.activeGroupCount()+1;
+ // Count the threads/groups during our traversal
+ // rather than use the often inaccurate ThreadGroup
+ // activeCount() and activeGroupCount()
+ ThreadGroupCount count = new ThreadGroupCount();
+
+ // traverse
+ String threadGroupInfo = getThreadGroupInfo(root, count);
+ // attach counters
+ String threadDump =
+ "<b>Total Threads:</b> " + count.threads + "<br>" +
+ "<b>Total Thread Groups:</b> " + count.groups + "<br>" +
+ threadGroupInfo;
- String rc=
- "<b>Total Threads:</b> "+activeThreads+"<br>"+
- "<b>Total Thread Groups:</b> "+activeGroups+"<br>"+
- getThreadGroupInfo(root) ;
- return rc;
+ return threadDump;
}
+
+ /**
+ * Return a listing of the active threads and thread groups.
+ *
+ * @jmx:managed-operation
+ */
+ public String listThreadCpuUtilization()
+ {
+ Set threads = getThreadCpuUtilization();
+ if (threads == null)
+ {
+ return("Thread cpu utilization requires J2SE5+");
+ }
+ else
+ {
+ long totalCPU = 0;
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<table><tr><th>Thread Name</th><th>CPU (milliseconds)</th></tr>");
+ for (Iterator i = threads.iterator(); i.hasNext();)
+ {
+ ThreadCPU thread = (ThreadCPU) i.next();
+ buffer.append("<tr><td>").append(thread.name).append("</td><td>");
+ buffer.append(thread.cpuTime).append("</td></tr>");
+ totalCPU += thread.cpuTime;
+ }
+ buffer.append("<tr><td> </td><td> </td></tr><tr><td>Total</td><td>");
+ buffer.append(totalCPU).append("</td></tr></table>");
+ return buffer.toString();
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Private //
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Get the Thread cpu utilization
+ *
+ * @return an ordered
+ */
+ private Set getThreadCpuUtilization()
+ {
+ if (threadMXBean == null)
+ return null;
+
+ try
+ {
+ TreeSet result = new TreeSet();
+ long[] threads = (long[]) getAllThreadIds.invoke(threadMXBean, null);
+ for (int i = 0; i < threads.length; ++i)
+ {
+ Long id = new Long(threads[i]);
+ Long cpuTime = (Long) getThreadCpuTime.invoke(threadMXBean, new Object[] { id });
+ Object threadInfo = getThreadInfo.invoke(threadMXBean, new Object[] { id, ZERO });
+ String name = (String) getThreadName.invoke(threadInfo, null);
+ result.add(new ThreadCPU(name, cpuTime.longValue()));
+ }
+ return result;
+ }
+ catch (Exception e)
+ {
+ log.warn("Error retrieving thread cpu utiliation", e);
+ return null;
+ }
+ }
+
+ /*
+ * Traverse to the root thread group
+ */
+ private ThreadGroup getRootThreadGroup()
+ {
+ ThreadGroup group = Thread.currentThread().getThreadGroup();
+ while (group.getParent() != null)
+ {
+ group = group.getParent();
+ }
- private String getThreadGroupInfo(ThreadGroup group)
+ return group;
+ }
+
+ /*
+ * Recurse inside ThreadGroups to create the thread dump
+ */
+ private String getThreadGroupInfo(ThreadGroup group, ThreadGroupCount count)
{
StringBuffer rc = new StringBuffer();
- rc.append("<BR><B>");
+ // Visit one more group
+ count.groups++;
+
+ rc.append("<br><b>");
rc.append("Thread Group: " + group.getName());
- rc.append("</B> : ");
+ rc.append("</b> : ");
rc.append("max priority:" + group.getMaxPriority() +
", demon:" + group.isDaemon());
@@ -356,25 +595,77 @@
group.enumerate(threads, false);
for (int i= 0; i < threads.length && threads[i] != null; i++)
{
- rc.append("<B>");
+ // Visit one more thread
+ count.threads++;
+
+ rc.append("<b>");
rc.append("Thread: " + threads[i].getName());
- rc.append("</B> : ");
+ rc.append("</b> : ");
rc.append("priority:" + threads[i].getPriority() +
", demon:" + threads[i].isDaemon());
- rc.append("<BR>");
+ // Output extra info with jdk5+, or just <br>
+ outputJdk5ThreadMXBeanInfo(rc, threads[i]);
}
ThreadGroup groups[]= new ThreadGroup[group.activeGroupCount()];
group.enumerate(groups, false);
for (int i= 0; i < groups.length && groups[i] != null; i++)
{
- rc.append(getThreadGroupInfo(groups[i]));
+ rc.append(getThreadGroupInfo(groups[i], count));
}
rc.append("</blockquote>");
return rc.toString();
}
+ /*
+ * Complete the output of thread info, with optional stuff
+ * when running under jdk5+, or just change line.
+ */
+ private void outputJdk5ThreadMXBeanInfo(StringBuffer sbuf, Thread thread)
+ {
+ // if ThreadMXBean has been found, we run under jdk5+
+ if (threadMXBean != null)
+ {
+ // use reflection all the way, until we base on jdk5
+ try
+ {
+ // get the threadId
+ Long threadId = (Long)getThreadId.invoke(thread, null);
+ // get the ThreadInfo object for that threadId, max StackTraceElement depth
+ Object threadInfo = getThreadInfo.invoke(threadMXBean,
+ new Object[] { threadId, new Integer(Integer.MAX_VALUE) });
+ // get misc info from ThreadInfo
+ Object threadState = getThreadState.invoke(threadInfo, null); // enum
+ String threadLockName = (String)getLockName.invoke(threadInfo, null);
+ Object[] stackTrace = (Object[])getStackTrace.invoke(threadInfo, null);
+
+ sbuf.append(", threadId:").append(threadId);
+ sbuf.append(", threadState:").append(threadState);
+ sbuf.append(", threadLockName:").append(threadLockName);
+ sbuf.append("<br>");
+ if (stackTrace.length > 0)
+ {
+ sbuf.append("<blockquote>");
+ for (int i = 0; i < stackTrace.length; i++)
+ {
+ sbuf.append(stackTrace[i]).append("<br>");
+ }
+ sbuf.append("</blockquote>");
+ }
+ }
+ catch (Exception ignore)
+ {
+ // empty
+ }
+ }
+ else
+ {
+ // no jdk5+ info to add, just change line
+ sbuf.append("<br>");
+ }
+ }
+
/**
* Display the java.lang.Package info for the pkgName
*
@@ -391,83 +682,176 @@
return info.toString();
}
- /**
- * Display the ClassLoader, ProtectionDomain and Package information for
- * the specified class.
- *
- * @return a simple html report of this information
- *
- * @jmx:managed-operation
- */
- public String displayInfoForClass(String className) throws Exception
+ private void displayPackageInfo(Package pkg, StringBuffer info)
{
- Class clazz = (Class)server.invoke(DEFAULT_LOADER_REPOSITORY,
- "findClass",
- new Object[] {className},
- new String[] {String.class.getName()});
- if( clazz == null )
- return "<h2>Class:"+className+" Not Found!</h2>";
- Package pkg = clazz.getPackage();
- if( pkg == null )
- return "<h2>Class:"+className+" has no Package info</h2>";
-
- StringBuffer info = new StringBuffer("<h1>Class: "+pkg.getName()+"</h1>");
- ClassLoader cl = clazz.getClassLoader();
- info.append("<h2>ClassLoader: "+cl+"</h2>\n");
- info.append("<h3>ProtectionDomain</h3>\n");
- info.append("<pre>\n"+clazz.getProtectionDomain()+"</pre>\n");
- info.append("<h2>Package: "+pkg.getName()+"</h2>");
- displayPackageInfo(pkg, info);
- return info.toString();
+ info.append("<pre>\n");
+ info.append("SpecificationTitle: "+pkg.getSpecificationTitle());
+ info.append("\nSpecificationVersion: "+pkg.getSpecificationVersion());
+ info.append("\nSpecificationVendor: "+pkg.getSpecificationVendor());
+ info.append("\nImplementationTitle: "+pkg.getImplementationTitle());
+ info.append("\nImplementationVersion: "+pkg.getImplementationVersion());
+ info.append("\nImplementationVendor: "+pkg.getImplementationVendor());
+ info.append("\nisSealed: "+pkg.isSealed());
+ info.append("</pre>\n");
}
-
- /**
- * This does not work as expected because the thread context class loader
- * is not used to determine which class loader the package list is obtained
- * from.
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Inner //
+ ///////////////////////////////////////////////////////////////////////////
+
+ /*
+ * Inner Helper class for fancy text graphs
+ *
+ * @author dimitris at jboss.org
*/
- public String displayAllPackageInfo()
+ private static class TextGraphHelper
{
- return "Broken right now";
+ // number conversions
+ static final DecimalFormat formatter = new DecimalFormat("#.##");
+ static final long KILO = 1024;
+ static final long MEGA = 1024 * 1024;
+ static final long GIGA = 1024 * 1024 * 1024;
+
+ // how many dashes+pipe is 100%
+ static final int factor = 70;
+ static char[] fixedline;
+ static char[] baseline;
+ static char[] barline;
+ static char[] spaces;
+ static
+ {
+ // cache a couple of Strings
+ StringBuffer sbuf0 = new StringBuffer();
+ StringBuffer sbuf1 = new StringBuffer();
+ StringBuffer sbuf2 = new StringBuffer();
+ StringBuffer sbuf3 = new StringBuffer();
+ sbuf0.append('+');
+ sbuf1.append('|');
+ sbuf2.append('|');
+ for (int i = 1; i < factor; i++)
+ {
+ sbuf0.append('-');
+ sbuf1.append('-');
+ sbuf2.append('/');
+ sbuf3.append(' ');
+ }
+ sbuf0.append('+');
+ fixedline = sbuf0.toString().toCharArray();
+ baseline = sbuf1.toString().toCharArray();
+ barline = sbuf2.toString().toCharArray();
+ spaces = sbuf3.toString().toCharArray();
+ }
+
+ private TextGraphHelper()
+ {
+ // do not instantiate
+ }
+
/*
- ClassLoader entryCL = Thread.currentThread().getContextClassLoader();
- ServiceLibraries libraries = ServiceLibraries.getLibraries();
- ClassLoader[] classLoaders = libraries.getClassLoaders();
- StringBuffer info = new StringBuffer();
- for(int c = 0; c < classLoaders.length; c ++)
+ * Make a text graph of a memory pool usage:
+ *
+ * +---------------------------| committed:10Mb
+ * +-------------------------------------------------+
+ * |//////////////// | | max:20Mb
+ * +-------------------------------------------------+
+ * +---------------| used:3Mb
+ *
+ * When max is unknown assume max == committed
+ *
+ * |-------------------------------------------------| committed:10Mb
+ * +-------------------------------------------------+
+ * |//////////////// | max:-1
+ * +-------------------------------------------------+
+ * |---------------| used:3Mb
+ */
+ public static void poolUsage(StringBuffer sbuf, long used, long committed, long max)
{
- ClassLoader cl = classLoaders[c];
- Thread.currentThread().setContextClassLoader(cl);
- try
+ // there is a chance that max is not provided (-1)
+ long assumedMax = (max == -1) ? committed : max;
+ // find out bar lengths
+ int localUsed = (int)(factor * used / assumedMax);
+ int localCommitted = (int)(factor * committed / assumedMax);
+ int localMax = factor;
+
+ sbuf.append("<blockquote><br>");
+ sbuf.append(baseline, 0, localCommitted).append("| committed:").append(outputNumber(committed)).append("<br>");
+ sbuf.append(fixedline).append("<br>");
+
+ // the difficult part
+ sbuf.append(barline, 0, localUsed);
+ if (localUsed < localCommitted)
{
- info.append("<h1>ClassLoader: "+cl+"</h1>\n");
- Package[] pkgs = Package.getPackages();
- for(int p = 0; p < pkgs.length; p ++)
- {
- Package pkg = pkgs[p];
- info.append("<h2>Package: "+pkg.getName()+"</h2>\n");
- displayPackageInfo(pkg, info);
- }
+ sbuf.append(localUsed > 0 ? '/' : '|');
+ sbuf.append(spaces, 0, localCommitted - localUsed - 1);
}
- catch(Throwable e)
+ sbuf.append('|');
+ if (localCommitted < localMax)
{
+ sbuf.append(spaces, 0, localMax - localCommitted - 1);
+ sbuf.append('|');
}
+ sbuf.append(" max:").append(outputNumber(max)).append("<br>");
+
+ sbuf.append(fixedline).append("<br>");
+ sbuf.append(baseline, 0, localUsed).append("| used:").append(outputNumber(used));
+ sbuf.append("</blockquote>");
}
- Thread.currentThread().setContextClassLoader(entryCL);
- return info.toString();
- */
+
+ private static String outputNumber(long value)
+ {
+ if (value >= GIGA)
+ {
+ return formatter.format((double)value / GIGA) + "Gb";
+ }
+ else if (value >= MEGA)
+ {
+ return formatter.format((double)value / MEGA) + "Mb";
+ }
+ else if (value >= KILO)
+ {
+ return formatter.format((double)value / KILO) + "Kb";
+ }
+ else if (value >= 0)
+ {
+ return value + "b";
+ }
+ else
+ {
+ return Long.toString(value);
+ }
+ }
}
+
+ private static class ThreadCPU implements Comparable
+ {
+ public String name;
+ public long cpuTime;
- private void displayPackageInfo(Package pkg, StringBuffer info)
+ public ThreadCPU(String name, long cpuTime)
+ {
+ this.name = name;
+ this.cpuTime = cpuTime / 1000000; // convert to millis
+ }
+
+ public int compareTo(Object o)
+ {
+ ThreadCPU other = (ThreadCPU) o;
+ long value = cpuTime - other.cpuTime;
+ if (value > 0)
+ return -1;
+ else if (value < 0)
+ return +1;
+ else
+ return name.compareTo(other.name);
+ }
+ }
+
+ /*
+ * Simple data holder
+ */
+ private static class ThreadGroupCount
{
- info.append("<pre>\n");
- info.append("SpecificationTitle: "+pkg.getSpecificationTitle());
- info.append("\nSpecificationVersion: "+pkg.getSpecificationVersion());
- info.append("\nSpecificationVendor: "+pkg.getSpecificationVendor());
- info.append("\nImplementationTitle: "+pkg.getImplementationTitle());
- info.append("\nImplementationVersion: "+pkg.getImplementationVersion());
- info.append("\nImplementationVendor: "+pkg.getImplementationVendor());
- info.append("\nisSealed: "+pkg.isSealed());
- info.append("</pre>\n");
+ public int threads;
+ public int groups;
}
}
Added: branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfoMBean.java
===================================================================
--- branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfoMBean.java 2006-09-01 22:29:13 UTC (rev 56513)
+++ branches/JBoss_4_0_0_Case10829/system/src/main/org/jboss/system/server/ServerInfoMBean.java 2006-09-01 23:58:37 UTC (rev 56514)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server;
+
+import javax.management.ObjectName;
+
+import org.jboss.mx.util.ObjectNameFactory;
+
+public interface ServerInfoMBean
+{
+ /** The default ObjectName */
+ ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.system:type=ServerInfo");
+
+ // Attributes ----------------------------------------------------
+
+ String getJavaVersion();
+ String getJavaVendor();
+
+ String getJavaVMName();
+ String getJavaVMVersion();
+ String getJavaVMVendor();
+
+ String getOSName();
+ String getOSVersion();
+ String getOSArch();
+
+ Integer getActiveThreadCount();
+ Integer getActiveThreadGroupCount();
+
+ /** Returns <tt>Runtime.getRuntime().maxMemory()<tt> on JDK 1.4 vms or -1 on previous versions. */
+ Long getMaxMemory();
+ Long getTotalMemory();
+ Long getFreeMemory();
+
+ /** Returns <tt>Runtime.getRuntime().availableProcessors()</tt> on JDK 1.4 vms or -1 on previous versions. */
+ Integer getAvailableProcessors();
+
+ /** Returns InetAddress.getLocalHost().getHostName(); */
+ String getHostName();
+
+ /** Returns InetAddress.getLocalHost().getHostAddress(); */
+ String getHostAddress();
+
+ // Operations ----------------------------------------------------
+
+ /**
+ * Return a listing of the thread pools on jdk5+.
+ * @param fancy produce a text-based graph when true
+ */
+ String listMemoryPools(boolean fancy);
+
+ /**
+ * Return a listing of the active threads and thread groups,
+ * and a full stack trace for every thread, on jdk5+.
+ */
+ String listThreadDump();
+
+ /**
+ * Return a sort list of thread cpu utilization.
+ */
+ String listThreadCpuUtilization();
+
+ /**
+ * Display the java.lang.Package info for the pkgName
+ */
+ String displayPackageInfo(String pkgName);
+
+}
More information about the jboss-cvs-commits
mailing list