Event translator: enrich OpenNMS notifications

Sometimes it might happen that you need “enriched” notifications from OpenNMS. Suppose you would like to send a notification including an information which is present on the asset view of your node: the Event Translator of OpenNMS is what you’re looking for.

At this Event Translator web page you can find the official documentation from OpenNMS but for a full implementation I suggest you to have a look at the following post.

Scenario: I will enrich the notification just for a specific category of devices that I use to call TimeClock. When one of these devices is down, It will send an enriched notification that include node label, ip address of the primary snmp interface and the description stored on the asset of the node. By default on OpenNMS notifications you won’t get these 2 additional information.

Translator-configuration.xml

First of all we’re going to add these 2 new event-translations at the /etc/opennms/translator-configuration.xml

<event-translation-spec uei="uei.opennms.org/nodes/nodeDown">
 <mappings>
 <mapping>
 <assignment name="uei" type="field" >
 <value type="constant" result="uei.opennms.org/translator/nodes/timeClockDown" />
 </assignment>
 <assignment name="interface" type="field">
 <value type="sql" result="SELECT ip.ipaddr FROM ipInterface ip LEFT JOIN category_node cn on cn.nodeid=ip.nodeid WHERE ip.nodeid = ?::integer AND ip.issnmpprimary = 'P' AND cn.categoryid=35" >
 <value type="field" name="nodeid" matches=".*" result="${0}" />
 </value>
 </assignment>
 <assignment name="description" type="parameter">
 <value type="sql" result="SELECT a.description FROM assets a LEFT JOIN category_node cn on cn.nodeid=a.nodeid WHERE a.nodeid = ?::integer AND cn.categoryid=35" >
 <value type="field" name="nodeid" matches=".*" result="${0}" />
 </value>
 </assignment>
 </mapping>
 </mappings>
</event-translation-spec>

 

<event-translation-spec uei="uei.opennms.org/nodes/nodeUp">
 <mappings>
 <mapping>
 <assignment name="uei" type="field" >
 <value type="constant" result="uei.opennms.org/translator/nodes/timeClockUp" />
 </assignment>
 <assignment name="interface" type="field">
 <value type="sql" result="SELECT ip.ipaddr FROM ipInterface ip LEFT JOIN category_node cn on cn.nodeid=ip.nodeid WHERE ip.nodeid = ?::integer AND ip.issnmpprimary = 'P' AND cn.categoryid=35" >
 <value type="field" name="nodeid" matches=".*" result="${0}" />
 </value>
 </assignment>
 <assignment name="description" type="parameter">
 <value type="sql" result="SELECT a.description FROM assets a LEFT JOIN category_node cn on cn.nodeid=a.nodeid WHERE a.nodeid = ?::integer AND cn.categoryid=35" >
 <value type="field" name="nodeid" matches=".*" result="${0}" />
 </value>
 </assignment>
 </mapping>
 </mappings>
</event-translation-spec>

Looking at the code you can see that on the sql query there’s embedded the TimeClock categoryid, in my case is 35. The easiest way to find that number is to run a query on the postgres db and check manually the corresponding number:

#for logging into the posgresql db
psql -U opennms

#query the categories table to look at names and associated id numbers
select * from categories;

So let’s describe what we’ve just done. Every time that a event like uei.opennms.org/nodes/nodeDown or uei.opennms.org/nodes/nodeUp occurs, OpenNMS will check if the result from the sql query is not empty. In that case it will trigger a translated event, respectively called:

  • uei.opennms.org/translator/nodes/timeClockDown
  • uei.opennms.org/translator/nodes/timeClockUp

These new events will piggyback 2 variables containing:

  1. ip.ipaddr from ipInterface table
  2. a.description from assets

events/Translator.default.events.xml

Now that OpenNMS is triggering the events, we should keep care on creating them. For this reason we’re going to add the following to the file /etc/opennms/events/Translator.defaults.events.xml.

<event>
<uei>uei.opennms.org/translator/nodes/timeClockDown</uei>
<event-label>Translator Enriched timeClockDown event</event-label>
<descr> Node is down on interface %interface% ; This event is generated when a timeclock is down; </descr>
<logmsg dest="logndisplay">'%parm[description]%'/'%interface%' is down. Enriched event uei.opennms.org/translator/nodes/timeClockDown triggered.</logmsg>
<severity>Minor</severity>
</event>

 

<event>
<uei>uei.opennms.org/translator/nodes/timeClockUp</uei>
<event-label>Translator Enriched timeClockUp event</event-label>
<descr> Node is up on interface %interface% /;This event is generated when a timeclock is up; </descr>
<logmsg dest="logndisplay">'%parm[description]%'/'%interface%' is up. Enriched event uei.opennms.org/translator/nodes/timeClockUp triggered.</logmsg>
<severity>Minor</severity>
</event>

Arrived at this point, a first test to fully understand how it works is needed. Restart OpenNMS first and once done  we can send a “test” event, using a dedicated Perl script written from the OpenNMS team, to check how the monitoring system behaves.

#find the nodeid of a TimeClock device (you can see it from the GUI under the assets view of the node
cd /usr/share/opennms/bin/
perl send-event.pl uei.opennms.org/nodes/nodeDown -n nodeid&lt;/pre&gt;

Check now on the Nodeid page what happened. You should see first of all a NodeDown event launched by you and then immediately a translated event triggered by OpenNMS like it’s here on the pic:

If you also see the event correctly translated, let’s go to the further 2 small steps missing.

notifications.xml

The current situation is that now we have a translated-event for TimeClock devices triggered once the NodeDown (or NodeUp) event occurs, this event contains 2 additional attributes that by default OpenNMS won’t provide: ip-address and description respectively on variables %interface% and %description%.

Logically we’re missing the notification for this translated-events. By editing the /etc/opennms/notification.xml file this is what should be added (the <rule> could be omitted)

<notification name="TimeClock is Down" status="on" writeable="yes">
 <uei>uei.opennms.org/translator/nodes/timeClockDown</uei>
 <description>TimeClock is Down</description>
 <rule>(categoryName = 'TimeClock')</rule>
 <destinationPath>helpdesk_admins</destinationPath>
 <text-message>Node %nodelabel% down at %time%. Timeclock device, please check it.&#xd;IP address: %interface%&#xd;
 Location: %parm[description]%</text-message>
 <subject>Notice #%noticeid% - Node %nodelabel% is down.</subject>
 <numeric-message>Notice #%noticeid% - Node %nodelabel% is down.</numeric-message>
 </notification>

Tips: if you create the notification from the GUI, the event name is the one displayed on the <event-label> field, specified on the events/Translator.default.events.xml file. In my case is called “<event-label>Translator Enriched timeClockUp event</event-label>”.

notifid-configuration.xml (optional but useful)

Latest step is the auto-acknowledge feature. This feature is by default enabled for NodeDown and NodeUp events but since we’ll substitute these default events with our translated events, at least for the TimeClock devices, we’ll have to enable OpenNMS to auto-acknowledge these new kind of events when they happen. In this way when the node come up again, you’ll also receive the notification automatically without creating a new notification also when the timeClockUp translated-event occurs.  For our purpose we have to add the following to the /etc/opennms/notifid-configuration.xml:

<auto-acknowledge resolution-prefix="RESOLVED: "
uei="uei.opennms.org/translator/nodes/timeClockUp" acknowledge="uei.opennms.org/translator/nodes/timeClockDown">
 <match>nodeid</match>
 </auto-acknowledge>

Now you should receive notifications including the 2 new attributes. Remember to call them by using the dedicated variables %interface% and %description% as it is on the notifications.xml added part.
Have fun with OpenNMS!