OpenNMS Integration

The following diagram depicts the various components involved in the life-cycle of an alarm and correlation with OpenNMS 24.0.0 and ALEC:

Alarm lifecyle

Events are generated by existing services that either process unsolicited messages or actively poll the monitored elements. These events are then sent to eventd where they are processed and enriched with the matching configuration.

alarmd listens for events that contain alarm meta-data and creates or updates alarms that correspond to these. In addition to the existing alarm processing that was present in OpenNMS before 24.0.0, alarmd now expose a series of hooks that can be used to alter/enrich the alarms when they are created.

ALEC leverages these hooks to perform additional processing and tag the alarms with a managed object type and managed object instance. See the Managed Object Tagging section bellow for more details.

OpenNMS also provides facilities to be notified when alarms are in some way modified. The direct datasource leverages API hooks directly into the run-time, whereas the Kafka datasource leverages the Kafka integration for interfacing externally.

Managed Object Tagging

Managed object tagging allows alarms to be further contextualized by associating them with a specific component instance (or inventory object in ALEC).

The process is flexible and configurable, allowing alarms to be associated with components beyond the existing node/interface/service model built-in to OpenNMS.

Let’s walk through an example and see how it works. Assume we have the following Syslog message:

%CDP-4-DUPLEX_MISMATCH: duplex mismatch discovered on ge1/1 (not half duplex), with sw-blue ge1/2 (half duplex).

We can use Syslogd to generate an event from the message using the following match:

<ueiMatch>
    <match type="regex" expression="%CDP-4-DUPLEX_MISMATCH\s*: duplex mismatch discovered on (\S+) \((.+)\), with (\S+) (\S+) \((.+)\)" />
    <uei>uei.opennms.org/vendor/cisco/syslog/duplexMismatch</uei>
    <parameter-assignment matching-group="1" parameter-name="aIfDescr" />
    <parameter-assignment matching-group="2" parameter-name="aDuplex" />
    <parameter-assignment matching-group="3" parameter-name="zHostname" />
    <parameter-assignment matching-group="4" parameter-name="zIfDescr" />
    <parameter-assignment matching-group="5" parameter-name="zDuplex" />
</ueiMatch>

And define an event using the following configuration:

<event>
    <uei>uei.opennms.org/vendor/cisco/syslog/duplexMismatch</uei>
    <event-label>CISCO defined syslog event: duplexMismatch</event-label>
    <descr>The duplex %parm[aIfDescr]% is set to %parm[aDuplex]% which
        does not match %parm[zDuplex]% on %parm[zHostname]% %parm[zIfDescr]%.
    </descr>
    <logmsg dest="logndisplay">Duplex mismatch on %parm[aIfDescr]% (%parm[aDuplex]% vs %parm[zDuplex]%)</logmsg>
    <severity>Warning</severity>
    <alarm-data reduction-key="%uei%:%dpname%:%nodeid%:%parm[aIfDescr]%" alarm-type="3">
        <managed-object type="snmp-interface-link"/>
    </alarm-data>
</event>

The event triggers an alarm of type 3 (trigger with no associated clear) and a specifies a managed object type of snmp-interface-link.

The Model reference shows that the snmp-interface-link type requires:

  1. aIfDescr

  2. zIfDescr

  3. zHostname

Referring to the syslog match definition above, we can see that we extract all of these tokens from the syslog message and convert them to event parameters. When the alarm is created, the ManagedObjectAlarmExt extension gets triggered, and will go through the process of resolving and canonicalizing the managed object.

In this case we search for a node with the same label as given in the zHostname attribute and attempt to find the ifIndex for SNMP interfaces with the given ifDescrs. We then update the managed object instance on the alarm to include the resolved attributes. When we need to store multiple attributes in managed object instance field we encode these in JSON so that they can be represented as a single string.

When the alarm is received by ALEC, it now contains sufficient information in the managed object type and instance fields so that it can be attached to a corresponding inventory object.