Version 4

    The AlarmManager Helper

     

    The org.jboss.monitor.alarm.AlarmManager is a helper class that can be used

    from mbeans that need to produce stateful or stateless

    org.jboss.monitor.alarm.AlarmNotification notifications.

     

    Instantiating AlarmManager

     

    To use the AlarmManager from an mbean extending ServiceMBeanSupport

    simply do:

       import org.jboss.monitor.alarm.Alarm;
       import org.jboss.monitor.alarm.AlarmManager;
       
       /** The alarm manager helper */
       private AlarmManager alm = new AlarmManager(this);
    

     

    If your mbean does not extend ServiceMBeanSupport, you need to provide

    an implementation of MBeanImplAccess (essentially an adapter class),

    so that AlarmManager has a way to:

    1. find out the producing mbean ObjectName

    2. generate unique sequence numbers

    3. emit notifications

     

    An example MBeanImplAccess for ServiceMBeanSupport is shown below:

        import org.jboss.monitor.alarm.MBeanImplAccess;
        import javax.management.ObjectName;
        import javax.management.Notification;
       
        /** alarm manager */
        AlarmManager alm =
          new AlarmManager(
             new MBeanImplAccess() {
                public ObjectName getMBeanName() { return getServiceName(); }
                public long getSequenceNumber() { return getNextNotificationSequenceNumber(); }
                public void emitNotification(Notification n) { sendNotification(n); }
          });
    

     

    Producing stateless alarm notifications

     

    The method of interest that will create and emit a stateless alarm notification,

    with the source, sequenceNumber and timeStamp automatically filled in, is

    the following:

       /**
        * Generates and sends an AlarmNotification.
        *
        * source, sequenceNumber, timeStamp
        * will be automatically filled.
        */   
       public void sendAlarm(String type, int severity, String message, Object userData)
    

    severity should correspond to one of the severities defined in

    org.jboss.monitor.alarm.Alarm. For example:

       ...
       alm.sendAlarm("jboss.security.violation", SEVERITY_MAJOR, "unauthorized access detected", extraInfo);
    

    If you want to include more than a single userData object in the alarm

    notification, you can store a Map instead. There is already a method on

    AlarmManager that will create a HashMap with a single entry:

       public void sendAlarm(String type, int severity, String message, String key, Object value)
    

    You can also produce alarm notifications on behalf of other mbeans.

    AlarmNotification has a target field that contains the ObjectName

    of the target mbean, in case the notification refers to a different mbean

    from the one that produced it. The ActiveAlarmTable knows how to correctly

    interpret this. AlarmManager provides a similar set of methods that take an

    additional target paramater, i.e.:

       public void sendAlarm(ObjectName target, String type, int severity, String message, Object userData)
       public void sendAlarm(ObjectName target, String type, int severity, String message, String key, Object value)   
    

     

    Producing stateful alarm notifications

     

    The first thing to understand is that stateful alarms are identified

    by notification type (e.g. jboss.alarm.memory.low) and that at any

    given point in time, for every mbean instance there is one logical

    fault state for that alarm: the alarm may be raised, or cleared.

     

    In the raised state the alarm has a severity described in

    org.jboss.monitor.alarm.Alarm that can vary from WARNING to UNKNOWN.

    In the cleared state the alarm has a NORMAL severity.

     

    The mbean should produce AlarmNotification notifications to describe

    the state changes of the alarm. The alarm is first CREATED with an

    initial severity, then CHANGED with an altered severity, then CLEARED,

    then CREATED again, and so on.

     

    AlarmManager helps generating those alarm state change notifications

    by keeping a internal type->severity map. Use setSeverity() to

    set the initial severity for an alarm, without producing any notification.

    If you don't, an initial severity Alarm.SEVERITY_NORMAL will be assumed.

       /**
        * Sets the severity of an Alarm, keyed by its type, without producing
        * an AlarmNotification, for the current mbean.
        */
       public void setSeverity(String type, int severity)
    

    Then just call setAlarm() whenever the severity for that alarm (type)

    changes. You can also provide a String message and the a userData object.

    If the provided severity, is different from the one stored in the internal

    map, for that particular alarm type, then the proper state change

    notification will be emitted. Otherwise, nothing will happen.

       /**
        * Sets the alarm for the current mbean, keyed by its type.
        * If severity has changed an AlarmNotification will be thrown.
        * The alarmState of the AlarmNotification will be either
        * Alarm.STATE_CREATED, Alarm.STATE_CHANGED or Alarm.STATE_CLEARED.
        */   
       public void setAlarm(String type, int severity, String message, Object userData)
    

    It is possible to produce stateful alarms on behalf of other mbeans,

    and there is also a convenience method for including a single key/value

    pair HashMap as userData.

     

    For an example of using the AlarmManager, look in the MemoryMonitor service:

      if (freeMemory <= criticalThreshold)
       {
          alm.setAlarm(
             "jboss.alarm.memory.low",
             Alarm.SEVERITY_CRITICAL,
             "Free memory in critical state",
             "freeMemory",
             new Long(freeMemory));
       }
       else if (freeMemory <= warningThreshold)
       {
          alm.setAlarm(
             "jboss.alarm.memory.low",
             Alarm.SEVERITY_WARNING,
             "Free memory getting low",
             "freeMemory",
             new Long(freeMemory));
       }
       else
       {
          alm.setAlarm(
             "jboss.alarm.memory.low",
             Alarm.SEVERITY_NORMAL,
             "Free memory at normal levels",
             "freeMemory",
             new Long(freeMemory));
       }
    

     

    Related:

     

    MemoryMonitor

     

     

    Referenced by: