<chapter id="mgmt_information">
  <title>Management Information</title>
  <para>JBoss Cache includes JMX MBeans to expose cache functionality and provide statistics that can be 
    used to analyze cache operations.  JBoss Cache can also broadcast cache events as MBean notifications for handling 
    via JMX monitoring tools.</para>
    
  <section>
    <title>JBoss Cache MBeans</title>
    <para>JBoss Cache provides an MBean that allows JMX access to a cache instance.  This MBean is accessible from an MBean 
    server through the service name specified in the cache instance's configuration.  For example, the Tomcat clustering cache instance
     is accessible through the service named "jboss.cache:service=TomcatClusteringCache."  This MBean can be used to perform 
     most cache operations via JMX.</para>
    <para>JBoss Cache also provides MBeans for each interceptor configured in the cache's interceptor stack.  These MBeans
    are used to capture and expose statistics related to cache operations.  They are hierarchically associated with the
    cache's primary MBean and have service names that reflect this relationship.  For example, a replication interceptor MBean 
    for the TomcatClusteringCache instance will be accessible through the service named
     "jboss.cache:service=TomcatClusteringCache,treecache-interceptor=ReplicationInterceptor."</para>
  </section>
  
  <section>
    <title>JBoss Cache Statistics</title>
    <para>JBoss Cache captures statistics in its interceptors and exposes the statistics through interceptor MBeans.  Cache interceptor
    MBeans are enabled by default; these MBeans can be disabled for a specific cache instance through the 
    <emphasis>UseInterceptorMbeans</emphasis> attribute.  See the Configuration chapter for further details on configuration of this 
    attribute.</para>
    <para>Each interceptor's MBean provides an attribute that can be used to disable maintenance of statistics for that interceptor. 
     Note that the majority of the statistics are provided by the CacheMgmtInterceptor MBean so this interceptor is the most significant 
     in this regard.  If you want to disable all statistics for performance reasons, you should utilize the <emphasis>UseInterceptorMbeans</emphasis>
      configuration setting as this will prevent the CacheMgmtInterceptor from being  included in the cache's interceptor stack when the 
      cache is started.</para>
      
      <para>Each interceptor provides the following common operations and attributes.</para>
      
      <itemizedlist>
      <listitem>dumpStatistics - returns a Map containing the interceptor's attributes and values.</listitem>
      <listitem>resetStatistics - resets all statistics maintained by the interceptor.</listitem>
      <listitem>setStatisticsEnabled(boolean) - allows statistics to be disabled for a specific interceptor.</listitem>
      </itemizedlist>
      
      	 <para>The following table describes the statistics currently available for JBoss Cache.</para>
      	 	 <table>
	 <title>JBoss Cache Management Statistics</title>
	 <tgroup cols="4">
	 <colspec colnum="1" colwidth="2*" />
	 <colspec colnum="2" colwidth="2*" />
	 <colspec colnum="3" colwidth="1*" />
	 <colspec colnum="4" colwidth="3*" />
	 <thead>
	 <row>
	    <entry>MBean Name</entry>
	    <entry>Attribute</entry>
	    <entry>Type</entry>
	    <entry>Description</entry>
	 </row>
	 </thead>
	 <tbody>
	 <row>
	    <entry>ActivationInterceptor</entry>
	    <entry>Activations</entry>
	    <entry>long</entry>
	    <entry>Number of passivated nodes that have been activated.</entry>
	 </row>
	 <row>
	    <entry>CacheLoaderInterceptor</entry>
	    <entry>CacheLoaderLoads</entry>
	    <entry>long</entry>
	    <entry>Number of nodes loaded through a cache loader.</entry>
	 </row>
	 <row>
	    <entry>CacheLoaderInterceptor</entry>
	    <entry>CacheLoaderMisses</entry>
	    <entry>long</entry>
	    <entry>Number of unsuccessful attempts to load a node through a cache loader.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>Hits</entry>
	    <entry>long</entry>
	    <entry>Number of successful attribute retrievals.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>Misses</entry>
	    <entry>long</entry>
	    <entry>Number of unsuccessful attribute retrievals.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>Stores</entry>
	    <entry>long</entry>
	    <entry>Number of attribute store operations.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>Evictions</entry>
	    <entry>long</entry>
	    <entry>Number of node evictions.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>NumberOfAttributes</entry>
	    <entry>int</entry>
	    <entry>Number of attributes currently cached.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>NumberOfNodes</entry>
	    <entry>int</entry>
	    <entry>Number of nodes currently cached.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>ElapsedTime</entry>
	    <entry>long</entry>
	    <entry>Number of seconds that the cache has been running.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>TimeSinceReset</entry>
	    <entry>long</entry>
	    <entry>Number of seconds since the cache statistics have been reset.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>AverageReadTime</entry>
	    <entry>long</entry>
	    <entry>Average time in milliseconds to retrieve a cache attribute, including unsuccessful
	    attribute retrievals.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>AverageWriteTime</entry>
	    <entry>long</entry>
	    <entry>Average time in milliseconds to write a cache attribute.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>HitMissRatio</entry>
	    <entry>double</entry>
	    <entry>Ratio of hits to hits and misses.  A hit is a get attribute operation that results in an object being 
            returned to the client.  The retrieval may be from a cache loader if the entry isn't in the local cache.</entry>
	 </row>
	 <row>
	    <entry>CacheMgmtInterceptor</entry>
	    <entry>ReadWriteRatio</entry>
	    <entry>double</entry>
	    <entry>Ratio of read operations to write operations.  This is the ratio of cache hits and misses to cache stores.</entry>
	 </row>
	 <row>
	    <entry>CacheStoreInterceptor</entry>
	    <entry>CacheLoaderStores</entry>
	    <entry>long</entry>
	    <entry>Number of nodes written to the cache loader.</entry>
	 </row>
	 <row>
	    <entry>InvalidationInterceptor</entry>
	    <entry>Invalidations</entry>
	    <entry>long</entry>
	    <entry>Number of cached nodes that have been invalidated.</entry>
	 </row>
	 <row>
	    <entry>PassivationInterceptor</entry>
	    <entry>Passivations</entry>
	    <entry>long</entry>
	    <entry>Number of cached nodes that have been passivated.</entry>
	 </row>
	 <row>
	    <entry>TxInterceptor</entry>
	    <entry>Prepares</entry>
	    <entry>long</entry>
	    <entry>Number of transaction prepare operations performed by this interceptor.</entry>
	 </row>
	 <row>
	    <entry>TxInterceptor</entry>
	    <entry>Commits</entry>
	    <entry>long</entry>
	    <entry>Number of transaction commit operations performed by this interceptor.</entry>
	 </row>
	 <row>
	    <entry>TxInterceptor</entry>
	    <entry>Rollbacks</entry>
	    <entry>long</entry>
	    <entry>Number of transaction rollbacks operations performed by this interceptor.</entry>
	 </row>
	 </tbody>
	 </tgroup>
	 </table>

  </section>
  
  <section>
    <title>Receiving Cache Notifications</title>
    <para>JBoss Cache users can register a listener to receive cache events as described in the Eviction Policies chapter.
	 Users can alternatively utilize the cache's management information infrastructure to receive these events via JMX
	 notifications.  Cache events are accessible as notifications by registering a NotificationListener for the CacheMgmtInterceptor
	 MBean.  This functionality is only available if cache statistics are enabled as described in the previous section.</para>
	 
	 <para>The following table depicts the JMX notifications available for JBoss Cache as well as the cache events to which they correspond.
	 These are the notifications that can be received through the CacheMgmtInterceptor MBean.  Each notification represents a single
	 event published by JBoss Cache and provides user data corresponding to the parameters of the event.</para>
	 <table>
	 <title>JBoss Cache MBean Notifications</title>
	 <tgroup cols="3">
	 <thead>
	 <row>
	    <entry>Notification Type</entry>
	    <entry>Notification Data</entry>
	    <entry>TreeCacheListener Event</entry>
	 </row>
	 </thead>
	 <tbody>
	 <row>
	    <entry>org.jboss.cache.CacheStarted</entry>
	    <entry>String : cache service name</entry>
	    <entry>cacheStarted</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.CacheStopped</entry>
	    <entry>String : cache service name</entry>
	    <entry>cacheStopped</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeCreated</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeCreated</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeEvicted</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeEvicted</entry>
	 </row>	 
	 <row>
	    <entry>org.jboss.cache.NodeLoaded</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeLoaded</entry>
	 </row>	 	 
	 <row>
	    <entry>org.jboss.cache.NodeModifed</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeModifed</entry>
	 </row>	 
	 <row>
	    <entry>org.jboss.cache.NodeRemoved</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeRemoved</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeVisited</entry>
	    <entry>String : fqn</entry>
	    <entry>NodeVisited</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.ViewChange</entry>
	    <entry>String : view</entry>
	    <entry>ViewChange</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeActivate</entry>
	    <entrytbl cols="1">
	       <tbody>
	          <row><entry rowsep="0">Object[0]=String: fqn</entry></row>
	          <row><entry>Object[1]=Boolean: pre</entry></row>
	       </tbody>
	    </entrytbl>
	    <entry>NodeActivate</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeEvict</entry>
	    <entrytbl cols="1">
	       <tbody>
	          <row><entry rowsep="0">Object[0]=String: fqn</entry></row>
	          <row><entry>Object[1]=Boolean: pre</entry></row>
	       </tbody>
	    </entrytbl>
	    <entry>NodeEvict</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeModify</entry>
	    <entrytbl cols="1">
	       <tbody>
	          <row><entry rowsep="0">Object[0]=String: fqn</entry></row>
	          <row><entry rowsep="0">Object[1]=Boolean: pre</entry></row>
	          <row><entry>Object[2]=Boolean: isLocal</entry></row>
	       </tbody>
	    </entrytbl>
	    <entry>NodeModify</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodePassivate</entry>
	    <entrytbl cols="1">
	       <tbody>
	          <row><entry rowsep="0">Object[0]=String: fqn</entry></row>
	          <row><entry>Object[1]=Boolean: pre</entry></row>
	       </tbody>
	    </entrytbl>
	    <entry>NodePassivate</entry>
	 </row>
	 <row>
	    <entry>org.jboss.cache.NodeRemove</entry>
	    <entrytbl cols="1">
	       <tbody>
	          <row><entry rowsep="0">Object[0]=String: fqn</entry></row>
	          <row><entry rowsep="0">Object[1]=Boolean: pre</entry></row>
	          <row><entry>Object[2]=Boolean: isLocal</entry></row>
	       </tbody>
	    </entrytbl>
	    <entry>NodeRemove</entry>
	 </row>    
	 </tbody>
	 </tgroup>
	 </table>
	 
	<para>The following is an example of how to programmatically receive cache notifications when running in a JBoss application server
	 environment.  In this example, the client uses a filter to specify which events are of interest.</para>
	 
	 <programlisting>
MyListener listener = new MyListener();
NotificationFilterSupport filter = null;
	 
// get reference to MBean server
Context ic = new InitialContext();
MBeanServerConnection server = (MBeanServerConnection)ic.lookup("jmx/invoker/RMIAdaptor");
	 
// get reference to CacheMgmtInterceptor MBean
String cache_service = "jboss.cache:service=TomcatClusteringCache";
String mgmt_service = cache_service + ",treecache-interceptor=CacheMgmtInterceptor";
ObjectName mgmt_name = new ObjectName(mgmt_service);
	 
// configure a filter to only receive node created and removed events
filter = new NotificationFilterSupport();
filter.disableAllTypes();
filter.enableType(CacheMgmtInterceptor.NOTIF_NODE_CREATED);
filter.enableType(CacheMgmtInterceptor.NOTIF_NODE_REMOVED);
	 
// register the listener with a filter
// leave the filter null to receive all cache events
server.addNotificationListener(mgmt_name, listener, filter, null);
	 
// ...
	 
// on completion of processing, unregister the listener
server.removeNotificationListener(mgmt_name, listener, filter, null);
  </programlisting>
	 
  <para>The following is the simple notification listener implementation used in the previous example.</para>
	<programlisting>
private class MyListener implements NotificationListener, Serializable {
   public void handleNotification(Notification notification, Object handback) {
      String message = notification.getMessage();
      String type = notification.getType();
      Object userData = notification.getUserData();
      System.out.println(type + ": "+message);
      if (userData == null) {
         System.out.println("notification data is null");
      }
      else if (userData instanceof String) {
         System.out.println("notification data: "+(String)userData);
      }
      else if (userData instanceof Object[]) {
         Object[] ud = (Object[])userData;
         for (int i = 0; i &gt; ud.length; i++) {
            System.out.println("notification data: "+ud[i].toString());
         }
      }
      else {
         System.out.println("notification data class: " + userData.getClass().getName());
      }
   }
} 
	</programlisting>
	
	<para>Note: the JBoss Cache management implementation only listens to cache events after a client registers to
	receive MBean notifications.  As soon as no clients are registered for notifications, the MBean will remove itself
	as a cache listener.</para>

  </section>
  
  <section>
    <title>Accessing Cache MBeans in a Standalone Environment</title>
    <para>JBoss Cache MBeans are readily accessed when running cache instances in an application server that provides
	an MBean server interface such as JBoss JMX Console.  Refer to server documentation for instructions on how to access
	MBeans running in a server's MBean container.</para>
    <para>JBoss Cache MBeans are also accessible when running in a non-server environment if the JVM is JDK 5.0 or later.
    When running a standalone cache in a JDK 5 environment, you can access the cache's MBeans as follows.</para>
    <para>
      <orderedlist>
        <listitem>Set the system property <emphasis>-Dcom.sun.management.jmxremote</emphasis> when starting the JVM 
        where the cache will run.</listitem>
        <listitem>Once the JVM is running, start the JDK 5 <emphasis>jconsole</emphasis> utility, located in the JDK's /bin directory.</listitem>
        <listitem>When the utility loads, you will be able to select your JVM and connect to it.  The JBoss Cache MBeans will be
        available on the MBeans panel.</listitem>
      </orderedlist>
    </para>
    <para>Note:  The <emphasis>jconsole</emphasis> utility will automatically register as a listener for cache notifications when connected 
      to a JVM running JBoss Cache instances.</para>

    <para>The following figure shows cache interceptor MBeans in <emphasis>jconsole</emphasis>.  Cache statistics are displayed 
      for the CacheMgmt interceptor:</para>

    <figure>
      <title>CacheMgmtInterceptor MBean</title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="images/CacheMgmtInterceptor.png" />
        </imageobject>
      </mediaobject>
    </figure>

  </section>
  
</chapter>
