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.
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.
DescriptionThis 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.
DescriptionThis 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,
DescriptionA 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.
DescriptionThe 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 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 --
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.
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.
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.
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.
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; }
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.
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; }
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.