Monitoring framework for iAS 7.0 SE.


Note:

Overview

iAS 7.0 SE monitoring framework is built on top of infrastructure provided by JMX (Java Management Extenstions). A set of MBeans dedicated to monitoring are registered to the MBeanServer running in every instance. These MBeans are queried from the administration server whenever a user requests statistics.

The communication between admin server and adminitered instance is done over the admin channel. For more details, please see the admin channel package description. Admin channel is used to send notifications from admin server to the instance. For monitoring, the notification MonitoringEvent is used. The notification supports four actions - start monitoring, stop monitoring, get monitoring data and list monitorable components.

A set of MBeans dedicated to monitoring task are created and registered to MBean server by the components that need to be monitored. These MBeans are organized in a tree structure with a pre defined root. Monitoring MBeans are identified by a type, name and a parent. The tree can be extended in any direction as long as a MBean does not conflict with any other MBean under its parent.

MonitoredObectType

An instance of this class rpresents the type of monitoring MBean. This class defines various public static constants representing known monitoring MBean types.

A type can be designated as singleton, which will enforce that only one MBean of that type exists under a given node of Monitoring MBean tree. For example, ejb pool is a singleton, because for every stateless session bean there is one pool.

Description

BaseMonitorMBean

This is the abstract super class of all monitoring MBeans. It implements the JMX interface DynamicMBean and also provides start and stop methods to manage monitoring state. All the basic tree management features are also available through this object.

Description

GenericMonitorMBean

This is a simple concrete sub-class of BaseMonitorMBean that exposes no monitorable statistics but can be used to group other monitoring MBeans by building up the tree of Monitoring MBeans. The only significant implementation in this class is those of methods startMonitoring and stopMonitoring call the same method on all its children,

Description

MonitoringHelper

A helper (utility) class to manage monitoring MBeans. This class uses GenericMonitorMBean to build up the tree, whenever a node does not exist in the tree.

Description

MBean Naming

The object name for monitoring MBeans is based on the position of the MBean in the tree. The name and type of MBean is represented by the property called name and mclass respectively. In addition to that, all object names contain properties describing its parent node.

The root MBean for monitoring is named ias:type=monitor,mclass=root,name=root,instance-name=ias1. All MBeans in iAS 7.0 SE have the same domain ias. The property type is required by MBeanServer and should always be set to monitor. The property instance-name is also required by the MBeanServer implementation and must be set to the name of the server instance. As there is only one root monitoring MBean, its name is always root. The value for mclass is derived from MonitoredObjectType.

If there is a MBean registered to monitor an application called app1, to its parent, the root monitoring MBean, the name will be ias:type=monitor,mclass=application,name=app1,root=root,instance-name=ias1. In addition to the required properties -- type, instance-name, mclass and name, the object name contains a reference to the parent MBean by applying a transform to the properties mclass and name of the parent -- the transform is to convert the value of mclass attribute to a property name and the value of the name attribute to the value of that property. A general rule is that a child MBean name contains all properties other than mclass and name with same values as in its parent.

More examples, a monitoring MBean for ejb module mod1 in application app1 will be named ias:type=monitor,mclass=ejb-module,name=mod1,application=app1,root=root,instance-name=ias1. A monitoring MBean for stateless session bean bean1 in module mod1 and application app1 will be named ias:type=monitor,mclass=stateless-bean,name=bean1,ejb-module=mod1,application=app1,root=root,instance-name=ias1.

CLI Name Mapping

CLI names address MBeans under root monitoring MBean in any instance. The CLI names are of the form --

      instanceName([.type[.name])*[.(star|attrName)]
  where,
     instanceName is name of server instance,
     type is derived from MonitoredObjectType,
     name is monitored component name,
     star is the character * (denotes all attributes)
     attrName is the name of the attribute
  

The other rules for CLI names are --

  1. (star|attrName) is required only for GET command. It should not be present for other commands.
  2. For a singleton MonitoredObjectType, name must not be specified. For non-singleton types both name and type must be specified.

For example, CLI name ias1.application.myApp.module.fortune_jar.stateless-bean.fortune.pool addresses the MBean monitoring pool for stateless session bean named fortune contained within the module fortune_jar in the J2EE application myApp.

Monitorable Attribute Type

There is a package com.sun.enterprise.admin.monitor.types that defines types for monitorable attributes (See Description). JMX supports three different types of Monitorable attributes -- Counter, Gauge and String and there are classes corresponding to them in this package.

JMX model for monitoring suggests one MBean for every monitorable attribute. The JMX monitoring MBean acts as an observer of the statistic exposed by some other MBean and collects statistic at pre defined interval. It also manages notification for thresold values. For iAS 7.0 SE, a simpler approach has been taken and an attempt has been made to collect as much data as possible, so that transition to full JMX model will be easier.

Another expectation for iAS 7.0 SE is that all monitorable attribute values have a simple toString() representation that is used to display statistic on the user interface.

Tutorial

Step 1: Create a Monitoring MBean

The first step is to determine the statistics that need to be exposed, their names and types (as defined in the package com.sun.enterprise.admin.monitor.types. A naming convention guide for monitorable attributes is maintained by user experience group which should be consulted while choosing names. The attributes should be exposed through MBeanInfo interface in a sub-class of BaseMonitorMBean and the MBean should then be registered to the tree of Monitoring MBeans.

Step 1a: Define Attributes

The goal of this step is to create/reference objects that will allow creation of a MBeanInfo object and also provide enough information to implement methods getMonitoringMetaData() and getMonitoredAttributeValues(). Following is a sample implementation suitable for use by other protected methods in BaseMonitorMBean --

    public class MyMonitorMBean extends BaseMonitorMBean {

        /**
         * A 2-d array initialized to attribute names and their types
         */
        private static Object[][] attrNameTypeArray = {
                {"context-root", StringMonitoredAttributeType.DEFAULT},
                {"count-requests", Counter.INTEGER},
                {"average-response-time-seconds", Counter.INTEGER},
                {"count-servlets-deployed", Counter.INTEGER}
            };
  

As stated earlier, the goal is to provide easy implementation of the methods getMBeanInfo(), getMonitoringMetaData() and getMonitoredAttributeValues(), so if you have other ways of implementing those methods, you do not need to declare a 2-d object array of monitorable attribute names and types.

Step 1b: Create MBeanInfo

This step is relevant only if you used 2-d object array in Step 1a. Continuing on from previous example --

        /**
         * Map of attribute names and their types
         */
        private static Map attrNameTypeMap;

        /**
         * Info on this MBean
         */
        private static MBeanInfo mBeanInfo;

        static {
            attrNameTypeMap = createAttrNameTypeMap(attrNameTypeArray);
            mBeanInfo = createMBeanInfo(attrNameTypeMap);
        }
  

The above steps create an instance of MBeanInfo that can be returned directly in the implementation for getMBeanInfo() --

        /**
         * Provides the exposed attributes and actions of the monitoring MBean using
         * an MBeanInfo object.
         * @return An instance of MBeanInfo with all attributes and actions exposed
         *         by this monitoring MBean.
         */
        public MBeanInfo getMBeanInfo() {
            return mBeanInfo;
        }
  
Step 1c: Implement getAttribute

The method getAttribute() is expected to return the value of specified monitored attribute and the code for that will vary greatly among various components being monitored. A sample implementation can be --

        /**
         * Obtains the value of a specific monitored attribute.
         * @param attribute The name of the attribute to be retrieved
         * @return The value of the attribute retrieved.
         * @throws AttributeNotFoundException if attribute name is not valid
         */
        public Object getAttribute(String attribute) {
            Object retval = null;
            if (attribute.equals(name1)) {
                retval = obj1.getAttr1();
            } else if (attribute.equals(name2)) {
                retval = obj2.getAttr2();
            } else {
                throw new AttributeNotFoundException("Invalid attribute!");
            }
            return retval;
        }
  

Another method getAttributes can be used to get values for more than one attributes in same call. This method should also be implemented in best possible way. At the minimum, the implementation can call getAttribute for every attribute that is on its parameter list.

Step 1d: Implement other abstract methods

The remaining abstract methods that must be implemented are getMonitoringMetaData() and getMonitoredAttributeValues(). A simple implementation that works alongwith the code in Step 1a and 1b above is --

        /**
         * Get a map of monitored attribute names and their types. The keys
         * in the map are names of the attribute and the values are their
         * types. The type value are instances of class
         * com.iplanet.ias.monitor.type.MonitoredAttributeType (or its
         * sub-classes)
         *
         * @return map of names and types of all monitored attributes
         */
        public Map getMonitoringMetaData() {
            return attrNameTypeMap;
        }

        /**
         * Get type of the specified monitored attribute.
         */
        public MonitoredAttributeType getAttributeType(String attrName) {
                MonitoredAttributeType type = null;
            if (attrNameTypeMap != null && attrName != null) {
                type = (MonitoredAttributeType)attrNameTypeMap.get(attrName);
            }
            return type;
        }
  
Step 2: Register MBean

The MBean should be created and registered appropriately, for it to become usable by the admin server. The class MonitoringHelper provides some ease of use methods to register MBeans.

The other approach is to get the root monitoring MBean by a call to the method getRootMonitorMBean in the class com.sun.enterprise.admin.server.core.AdminService. The monitoring provider can then traverse through to the node of its interest, starting from the top node in monitoring MBean tree, and then add itself as child to that node using the method addChild() from class BaseMonitorMBean.

Of course, a combination of the two approaches is to use MonitoringHelper to register an MBean, keep a reference to it and then use addChild method on it to expand the tree further.