For the complete documentation index, see llms.txt. This page is also available as Markdown.

OpenNMS Integration

OpenNMS is an open-source network monitoring and management platform that discovers your infrastructure, collects performance data, and turns events into alarms. With the ilert OpenNMS plugin, alarms are forwarded to ilert as alerts, so your on-call team is notified through SMS, phone calls, and push notifications, while acknowledging or clearing the alarm in OpenNMS keeps the ilert alert in sync.

System requirements

  • OpenNMS Horizon 35 (or higher)

  • Shell access to the OpenNMS server and access to the Karaf console over SSH on port 8101, default password admin. From the OpenNMS host, or from anywhere the port is published, use ssh admin@localhost -p 8101. On the Docker image, run docker exec -it <container> ssh admin@localhost -p 8101 unless you publish 8101 on the host

  • JDK 17 and Maven, only if you build the plugin from source instead of downloading a release

Locate your OpenNMS install root

This guide writes paths as $OPENNMS_HOME, which is the OpenNMS install root. The packages do not export that variable, so it is empty in a normal login shell: a command pasted as-is writes to /deploy/ at the filesystem root instead of into OpenNMS, and the plugin is never picked up. Look up your root and copy it before you continue.

Installation
Install root

RPM or Debian package

/usr/share/opennms

Docker image or tarball

/opt/opennms

In ilert: Create an OpenNMS alert source

  1. Go to Alert sources -> Alert sources and click Create new alert source.

  1. Search for OpenNMS in the search field, click the OpenNMS tile, and then Next.

  1. Give your alert source a name, optionally assign teams, and click Next.

  2. Select an escalation policy by creating a new one or assigning an existing one.

  1. Select your Alert grouping preference and click Continue setup. You may click Do not group alerts for now and change it later.

  1. The next page shows additional settings, such as custom alert templates or notification priority. Click Finish setup for now.

  2. On the final page, copy the generated events URL verbatim. You will use it to configure the plugin on the OpenNMS server. It looks like this:

If different classes of alarm should reach different teams, create one alert source per team. Each one gets its own events URL, and you repeat the alert source settings once per alert source with a different filter.

In OpenNMS: Install the plugin

Get the plugin

Download opennms-ilert-plugin.tar.gz from the releases page of the ilert OpenNMS plugin and unpack it. Besides the .kar file, the archive contains the license and shasum256.txt, so you can verify the download:

Alternatively, build the plugin yourself, which requires JDK 17 and Maven:

The kar is created in assembly/kar/target/. Two kars land there: take opennms-ilert-plugin-<version>.kar, which is around 6 MB. The 3 KB org.opennms.plugins.ilert.assembly.kar-<version>.kar next to it is a Maven artifact, not the plugin, and deploying it installs nothing.

Deploy the plugin

Either way you end up with a file named opennms-ilert-plugin-<version>.kar. Copy it into the OpenNMS deploy directory, then tell Karaf to install the feature on every boot.

sudo cp and sudo tee write to the host filesystem, not into the container, so neither works here. Move both files in with docker cp instead, against the literal /opt/opennms root:

docker cp writes to the container's own layer, so both files are gone the next time the container is recreated. Keep deploy/ and etc/ on volumes, or bake the kar and the boot file into your image, if the plugin has to survive an image update.

Restart OpenNMS to pick up the plugin, or docker restart <container> on the Docker image. To avoid the restart, install the feature from the Karaf console instead. The boot file still makes sure that it survives future restarts:

Confirm the installation

Confirm that the feature is Started and the bundle is Active:

If the bundle is listed as Installed instead of Active, it failed to resolve. Run bundle:diag <id> to see the unsatisfied requirement.

Nothing is forwarded yet, since the plugin has no alert source configured. That is the next step.

In OpenNMS: Configure the plugin

Alert source settings

Each ilert alert source is one plugin service with its own URL, filter, and hold-down delay. Create it from the Karaf console:

The --alias is only a label for this service and becomes part of the filename. The command above writes $OPENNMS_HOME/etc/org.opennms.plugins.ilert.services-production.cfg, and you can create that file yourself instead:

Either way, the change takes effect within seconds and does not require a restart. Repeat this step once per ilert alert source, giving each a different --alias.

Property
Required
Meaning

url

yes

The events URL you copied in ilert. A service without a url does not start and logs an error.

jexlFilter

in practice, yes

Which alarms this service forwards. Without a filter, nothing is forwarded: the plugin logs a warning and stays idle.

holdDownDelay

no

An ISO-8601 duration such as PT5M, which delays alerts so that alarms clearing inside the window never page. Absent means send immediately.

Global settings

Every ilert alert carries a link back to the alarm in OpenNMS. The link defaults to 127.0.0.1, which is of no use on a responder's phone, so set it to a URL your team can actually reach. These settings apply to the whole OpenNMS instance, not to a single alert source:

Property
Default
Meaning

alarmDetailsUrlPattern

http://127.0.0.1:8980/opennms/alarm/detail.htm?id=%d

Deep link to the alarm. Must contain exactly one %d for the alarm ID; a literal percent sign has to be escaped as %%.

client

OpenNMS

The label shown on that link in ilert. Worth changing if you run more than one OpenNMS instance.

A malformed pattern does not stop alerts. The plugin logs the problem once at startup and sends alerts without the link instead of not sending them at all.

Choose which alarms are forwarded

jexlFilter is a JEXL expression that is evaluated per alarm. The alarm is bound to the variable alarm, and any getter on the OpenNMS Alarm model is reachable as a property. The expression must evaluate to a boolean. An expression that throws, or that returns something else, drops the alarm and logs a warning.

Some starting points:

The plugin ships a Karaf command that runs an expression against the alarms currently in your database, so you can see what a filter would have caught without waiting for the next outage:

Option
Effect

-c

Report only the count, which is useful for sizing a filter against a busy database.

-p

Print the ilert payload that each matching alarm would produce, without the alarm deep link.

-a <id>

Evaluate against a single alarm by ID and report whether that alarm would be forwarded.

-a is the fastest way to find out why a specific alarm did not page. Here a minor nodeLostService alarm falls below a major-and-above filter:

Alert priority

The plugin derives the priority of the ilert alert from the severity of the alarm. The mapping is fixed and there is no plugin setting for it:

Alarm severity
ilert priority

CRITICAL, MAJOR

High

INDETERMINATE, CLEARED, NORMAL, WARNING, MINOR

Low

Priority decides how the alert notifies: a high priority alert runs your escalation policy, while a low priority alert notifies through each responder's low-priority notification rules and is never escalated.

This matters as soon as you widen jexlFilter below major. A WARNING or MINOR alarm creates an alert in ilert, which is easy to read as proof that the integration pages correctly, but the escalation policy never runs for it. If those alarms should page, override the priority on the ilert side with dynamic priority mapping on the alert source. Run opennms-ilert:eval-jexl -p to see which payload fields you can map from.

Delay alerts for short outages

Service pollers sometimes report brief outages that resolve themselves. With holdDownDelay set, the plugin waits before sending the alert. If the alarm clears inside that window, the alert is cancelled and nobody is paged:

The value is an ISO-8601 duration such as PT30S, PT5M, or PT1H. An unparseable value is reported in the log and treated as no delay, so a typo does not stop alerts from being sent.

Two details are worth knowing:

  • The deadline does not move. While an alert is held, further updates to the same alarm replace the pending payload but keep the original deadline. An alarm that escalates during the wait pages with its latest severity, and an alarm that updates every few seconds cannot push its own deadline out forever.

  • Only new alerts are delayed. If the alarm is acknowledged or clears while the alert is still held, nothing is sent to ilert at all.

Verify the integration

Raise a real alarm through the OpenNMS REST API. nodeLostService is a good choice, because its reduction key varies per interface and service, so each test creates a distinct alert instead of deduplicating onto the previous one. Use a nodeid that exists on your system:

A successful POST returns 202, and within a few seconds the alert appears in your ilert alert source.

nodeLostService raises a minor alarm, so the major-and-above filter from Alert source settings drops it and nothing reaches ilert. Widen the filter to alarm.severity.id >= 5 for the duration of the test, and set it back afterwards. The alert then arrives with low priority and does not run your escalation policy, which is expected here; see Alert priority.

Then exercise the rest of the life cycle:

  • Acknowledge the alarm in the OpenNMS UI. The ilert alert is accepted. Acknowledging does not resolve the alert.

  • Clear the alarm by sending the matching nodeRegainedService event with the same nodeid, interface, and service. The ilert alert is resolved.

All three steps map onto one ilert alert, because the plugin uses the reduction key of the alarm as the ilert alert key.

Watch what the plugin does

Enable debug logging from the Karaf console:

Then follow $OPENNMS_HOME/logs/karaf.log. A successful delivery looks like this:

To keep debug logging enabled across restarts, add the following to $OPENNMS_HOME/etc/org.ops4j.pax.logging.cfg:

The plugin also reports on itself through OpenNMS events, which is the better signal for a dashboard or a long-running check:

  • uei.opennms.org/ilert/sendEventSuccessful — the event was delivered.

  • uei.opennms.org/ilert/sendEventFailed — the plugin gave up after the third attempt. This raises an alarm of its own, which is cleared automatically by the next success.

Neither of these two events is ever forwarded to ilert, so they cannot cause a feedback loop.

FAQ

Will alerts in ilert be resolved automatically?

Yes, as soon as the alarm is cleared or deleted in OpenNMS, the plugin sends a RESOLVE event and the corresponding alert in ilert is resolved.

Will alerts in ilert be accepted automatically?

Yes, as soon as the alarm is acknowledged in OpenNMS, the plugin sends an ACCEPT event and the corresponding alert in ilert is accepted.

What happens if ilert cannot be reached?

ALERT events are attempted up to three times, waiting two seconds and then eight seconds between the attempts, which the log counts as attempt 1 of 3. Once the attempts are exhausted, the plugin raises uei.opennms.org/ilert/sendEventFailed locally, which creates an alarm containing the error detail. That alarm is worth wiring to a secondary notification path, and it clears automatically on the next successful send for the same alarm. ACCEPT and RESOLVE events are sent once and are not retried, because they are sent from the alarm life cycle callback, which must not block.

Nothing arrives in ilert and the log is quiet. What can I do?

This is almost always a missing or non-matching jexlFilter. Look for No 'jexlFilter' configured ... No alarms will be forwarded until one is set in karaf.log, then check your expression with opennms-ilert:eval-jexl -a <alarm-id> '<your filter>'.

The service does not start. What can I do?

Look for No 'url' is configured for iLert service pid: ... in the log and confirm that the configuration landed with config:list '(service.pid=org.opennms.plugins.ilert.services*)'.

The log shows iLert answered with status 401 or 404.

The URL is wrong or the alert source was deleted. Copy the events URL from your alert source in ilert again. To check a URL without raising an alert, post an empty JSON body to it. A valid URL answers 400 missing 'alertKey' field, which means the request reached the alert source and only the payload was wrong. A 404 means the URL itself is bad.

Deliveries fail with timeouts.

The OpenNMS host has to reach api.ilert.com over outbound HTTPS. Test this from the OpenNMS host itself, and keep in mind that a container has its own view of the network.

The feature disappears after a restart.

The wait-for-kar value in $OPENNMS_HOME/etc/featuresBoot.d/ilert.boot does not match the kar name. Compare it against kar:list in the Karaf console; it must be the filename of the .kar file without the .kar extension.

The link on the alert does not open.

The alarmDetailsUrlPattern points to a host that your browser cannot reach, see Global settings.

After an upgrade, the old version keeps running.

Karaf caches kar contents under $OPENNMS_HOME/data/kar/<kar-name>/ and does not overwrite a cached kar of the same version, so everything looks Active while the old code runs. Release versions avoid this. If you hit it with a snapshot build, clear the cache explicitly. From the Karaf console:

Then on the shell:

On the Docker image, run the same two removals inside the container. The wildcards need a shell, so pass them to sh -c rather than to rm directly:

Copy the new kar in afterwards and install the feature again. Removing the file from deploy/ before copying the new one in matters: copying over a filename that Karaf still holds state for makes its redeploy fail with The KAR ... is not installed, and the kar is then never extracted. To confirm which build is live, check Bnd-LastModified in bundle:headers <bundle-id> against the jar you deployed.

Can I forward alarms to more than one alert source?

Yes, create one service configuration per alert source, each with its own --alias, url, and jexlFilter.

Last updated

Was this helpful?