Table of Contents
This appendix introduces four examples of monitoring JEUS MBean information.
Servlet thread information monitoring
ThreadPool information monitoring
JVM information monitoring
JDBC datasource (DB connection pool) monitoring
In the examples, RemoteMBeanServerFactory class is used to get information from MBean servers. For other methods of getting information from MBean servers, refer to "Chapter 3. JMX Application Development".
The example below monitors information about web engine listeners. In Particular, the thread pool and each thread are monitored.
The information monitored is:
The number of currently assigned worker threads (current thread count)
The maximum number of threads allowed in the thread pool (max thread count)
The number of clients in the wait-queue (wait queue count)
See the following example of monitoring the servlet thread information.
package monitoring; import java.util.*; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.ObjectInstance; import javax.management.MalformedObjectNameException; import javax.management.MBeanServerInvocationHandler; import jeus.management.j2ee.servlet.*; public class ServletThreadInfo { public void showInfo(MBeanServerConnection mBeanServer, String targetName) throws Exception { System.out.println("=== Servlet Thread Info ==="); // Get the object name of the servlet engine using JMX Standard API // Otherwise, the object name could be queried through MBeanServer. // Please see JEUS MBean API javadoc for more concrete name, key properties. ObjectName name = new ObjectName("JEUS:jeusType=WebEngine,J2EEServer=" + targetName + ",*"); Set names = mBeanServer.queryMBeans(name, null); if (names == null || names.size() == 0) { System.out.println("there is no servlet engine"); return; } // Choose one servlet engine from the returned object names Iterator it = names.iterator(); ObjectName fullName = null; while (it.hasNext()) { fullName = ((ObjectInstance)it.next()).getObjectName(); break; } assert fullName != null; WebEngineMoMBean engineMBean = (WebEngineMoMBean)MBeanServerInvocationHandler.newProxyInstance(mBeanServer, fullName, WebEngineMoMBean.class, false); // Get listeners from WebEngine String[] listeners = engineMBean.getWebListeners(); if(listeners == null || listeners.length == 0){ return; } String webEngineName = engineMBean.getObjectName().getKeyProperty("name"); for(int i = 0; i < listeners.length; i++) { ObjectName listener = new ObjectName(listeners[i]); WebListenerMoMBean listenerMBean= (WebListenerMoMBean) MBeanServerInvocationHandler.newProxyInstance (mBeanServer, listener, WebListenerMoMBean.class, false); String[] tpoolNames = listenerMBean.getThreadPools(); // Get stats from thread pools if (tpoolNames != null) { showThreadPoolStats(mBeanServer, webEngineName, tpoolNames); } } System.out.println(); } private void showThreadPoolStats(MBeanServerConnection mBeanServer, String contextGroupName, String[] tpoolNames) throws MalformedObjectNameException { for (int k = 0; k < tpoolNames.length; k++) { ObjectName tpool = new ObjectName(tpoolNames[k]); System.out.println("[MBean] " + tpool); ThreadPoolMoMBean tpoolMBean = (ThreadPoolMoMBean)MBeanServerInvocationHandler.newProxyInstance( mBeanServer,tpool, ThreadPoolMoMBean.class, false); ThreadPoolStatsImpl stats = (ThreadPoolStatsImpl) tpoolMBean.getstats(); System.out.println("Listener: " + contextGroupName + "/" + tpool.getKeyProperty("name")); System.out.println("- current thread count : " + stats.getAllThreadCount().getCount()); System.out.println("- max thread count : " + stats.getMaxThreadCount().getCount()); if (stats.getStatisticVersion() == ThreadPoolStatsImpl.NIO_VERSION) { // pipeline System.out.println("- total connection count : " + stats.getTotalConnectionCount().getCount()); System.out.println("- max queue count : " + stats.getMaxQueueCount().getCount()); System.out.println("- current queue count : " + stats.getCurrentQueueCount().getCount()); System.out.println("- remain queue count : " + stats.getRemainQueueCount().getCount()); System.out.println("- peak queue count : " + stats.getPeakQueueCount().getCount()); System.out.println("- total queue count : " + stats.getTotalQueueCount().getCount()); System.out.println("- difference queue 1m count : " + stats.getDifferenceQueue1MCount().getCount()); System.out.println("- difference queue 5m count : " + stats.getDifferenceQueue5MCount().getCount()); System.out.println("- difference queue 15m count : " + stats.getDifferenceQueue15MCount().getCount()); System.out.println("- overflow queue count : " + stats.getOverflowCount().getCount()); System.out.println("- average queue time : " + stats.getQueueWaitTimeAverage().getCount() + "(ms)"); } else { System.out.println("- wait queue count : " + stats.getWaitQueueCount().getCount()); } System.out.println(); } } }
In the following example of monitoring the thread pool information, thread pool states used in JEUS are monitored.
The information monitored is:
Thread pool size
Thread pools statistics
Thread execution time statistics
Wait-queue size statistics (size stats)
See the following example of monitoring the thread information.
package monitoring; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.j2ee.statistics.TimeStatistic; import javax.management.j2ee.statistics.RangeStatistic; import javax.naming.*; import jeus.jndi.JNSConstants; import jeus.management.JMXConstants; import jeus.management.RemoteMBeanServerFactory; import jeus.management.j2ee.thread.ThreadPoolMBean; import jeus.management.j2ee.thread.stats.ThreadPoolStats; public class ThreadPoolInfo { public void showInfo(MBeanServerConnection mBeanServer, String name) throws Exception { System.out.println("=== ThreadPool Info ==="); // Get the object names of the thread pools. // Please see JEUS MBean API javadoc for more concrete name, key // properties. ObjectName objectNames = new ObjectName("JEUS:jeusType=ThreadPool,*"); Set tpMBeans = mBeanServer.queryMBeans(objectNames, null); for (Iterator i = tpMBeans.iterator(); i.hasNext();) { ObjectName mbeanName = ((ObjectInstance) i.next()).getObjectName(); // thread pool name System.out.println("[Thread-pool : " + mbeanName.getKeyProperty("name") + "]"); System.out.println("[MBean] " + mbeanName); ThreadPoolMBean pool = (ThreadPoolMBean)MBeanServerInvocationHandler.newProxyInstance( mBeanServer, mbeanName, ThreadPoolMBean.class, false); // ThreadPool Size System.out.println("-size : " + pool.getPoolSize()); System.out.println("-core size : " + pool.getCorePoolSize()); System.out.println("-largest Size : " + pool.getLargestPoolSize()); System.out.println("-max size : " + pool.getMaximumPoolSize()); System.out.println("-queue size : " + pool.getWorkQueueSize()); // ThreadPool Stats ThreadPoolStats stats = (ThreadPoolStats) pool.getstats(); TimeStatistic executionTimeStats = stats.getThreadExecutionTime(); TimeStatistic waitingTimeStats = stats.getQueueWaitingTime(); System.out.println("# Thread Execution Time Stats"); System.out.println("--unit : " + executionTimeStats.getUnit()); System.out.println("--count : " + executionTimeStats.getCount()); System.out.println("--min time : " + executionTimeStats.getMinTime()); System.out.println("--max time : " + executionTimeStats.getMaxTime()); System.out.println("# Queue Waiting Time Stats"); System.out.println("--unit : " + waitingTimeStats.getUnit()); System.out.println("--count : " + waitingTimeStats.getCount()); System.out.println("--min time : " + waitingTimeStats.getMinTime()); System.out.println("--max time : " + waitingTimeStats.getMaxTime()); } } }
In the following example of monitoring the JVM information, JVMs of JEUS nodes or engines are monitored.
The information monitored is:
Total JVM size
JVM heap size
JVM uptime
See the following example of monitoring the JVM information.
package monitoring; import java.util.Iterator; import java.util.Set; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.j2ee.statistics.BoundedRangeStatistic; import javax.management.j2ee.statistics.CountStatistic; import javax.management.j2ee.statistics.RangeStatistic; import jeus.management.j2ee.JVMMBean; import jeus.management.j2ee.statistics.JVMStatsImpl; public class JVMInfo { public void showInfo(MBeanServerConnection mBeanServer, String targetName) throws Exception { System.out.println("=== JVM Statistics ==="); ObjectName objectName = new ObjectName("JEUS:j2eeType=JVM,name=" + targetName + ",*"); Set jvmMBeans = mBeanServer.queryMBeans(objectName, null); for (Iterator i = jvmMBeans.iterator(); i.hasNext();) { ObjectName objName = ((ObjectInstance) i.next()).getObjectName(); System.out.println("[MBean] " + objName); // JVMMBean Stats JVMMBean jvm = (JVMMBean)MBeanServerInvocationHandler.newProxyInstance( mBeanServer, objName, JVMMBean.class, false); JVMStatsImpl jvmstatsimpl = (JVMStatsImpl) jvm.getstats(); RangeStatistic totalSize = jvmstatsimpl.getTotalSize(); BoundedRangeStatistic heapSize = jvmstatsimpl.getHeapSize(); CountStatistic upTime = jvmstatsimpl.getUpTime(); // JVM Total Size System.out.println("[Total Size]"); System.out.println("-unit : " + totalSize.getUnit()); System.out.println("-current : " + totalSize.getCurrent()); System.out.println("-min size : " + totalSize.getLowWaterMark()); System.out.println("-max size : " + totalSize.getHighWaterMark()); // JVM Heap Size System.out.println("[Heap Size]"); System.out.println("-unit : " + heapSize.getUnit()); System.out.println("-current : " + heapSize.getCurrent()); System.out.println("-min Size : " + heapSize.getLowWaterMark()); System.out.println("-max Size : " + heapSize.getHighWaterMark()); System.out.println("-lower bound : " + heapSize.getLowerBound()); System.out.println("-upper bound : " + heapSize.getUpperBound()); // JVM UpTime System.out.println("[Up Time]"); System.out.println("-unit : " + upTime.getUnit()); System.out.println("-count : " + upTime.getCount()); System.out.println("-start time : " + upTime.getStartTime()); } } }
In the following example of monitoring the JDBC datasource (DB connection pool), DB connection pools in JEUS servers are monitored. The example also shows how to obtain an MBean connection by using the javax.management.remote.JMXConnector class.
The details of the example are:
Connects to a specific MBean server.
Queries the jeus.management.j2ee.JDBCResourceMBean object, and periodically records information about the current connection pools to a file.
A connection pool is created when the service is actually called.
See the following example of monitoring the DB connection pool.
package monitoring; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.j2ee.statistics.JDBCConnectionPoolStats; import javax.management.j2ee.statistics.JDBCStats; import javax.management.remote.JMXConnector; import javax.naming.Context; import javax.naming.InitialContext; import jeus.management.JMXConstants; import jeus.management.j2ee.JDBCResourceMBean; public class DBStatsClient { public static void main(String[] args) { String serverName = "changeplz"; //e.g. server1 Hashtable<String, Object> env = new Hashtable<String,Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "jeus.jndi.JNSContextFactory"); env.put(Context.URL_PKG_PREFIXES, "jeus.jndi.jns.url"); env.put(Context.PROVIDER_URL, "localhost:9736"); MBeanServerConnection mbsc; try { InitialContext ctx = new InitialContext(env); JMXConnector connector = (JMXConnector)ctx.lookup( JMXConstants.JNDI_BINDING_PREFIX + serverName); connector.connect(); mbsc = connector.getMBeanServerConnection(); } catch (Exception e) { e.printStackTrace(); return; } System.out.println("mbean server connection successfully established"); Set mbeans; try { ObjectName dbstats = new ObjectName("JEUS:j2eeType=JDBCResource,*"); mbeans = mbsc.queryMBeans(dbstats, null); } catch (Exception e) { e.printStackTrace(); return; } System.out.println("Successfully get JDBCResource"); File file = new File(serverName+".log"); FileOutputStream stream = null; try { stream = new FileOutputStream(file); } catch (IOException e) { e.printStackTrace(); return; } while(true) { for (Iterator iter = mbeans.iterator();iter.hasNext();) { ObjectName jdbcResourceMBeanName = ((ObjectInstance) iter.next()).getObjectName(); JDBCResourceMBean jdbcResource = (JDBCResourceMBean) MBeanServerInvocationHandler.newProxyInstance( mbsc, jdbcResourceMBeanName, JDBCResourceMBean.class, false); JDBCStats jdbcStats = (JDBCStats) jdbcResource.getstats(); SimpleDateFormat format = new SimpleDateFormat("[MM-dd]HH:mm:ss"); StringBuilder builder = new StringBuilder(); builder.append("[STA] "); for (JDBCConnectionPoolStats cpStats : jdbcStats.getConnectionPools()) { String output =format.format(new Date(System.currentTimeMillis())) + " name:[" +cpStats.getJdbcDataSource() + "]" + " total:[" +cpStats.getPoolSize().getCurrent() +"]" + " use:[" + (cpStats.getPoolSize().getCurrent() - cpStats.getFreePoolSize().getCurrent()) +"] "; builder.append(output); } builder.append("/n"); try { stream.write(builder.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); return; } } try { Thread.sleep(10000); } catch (InterruptedException e) { return; } } } }