Think of the filter (also referred to as a rule) as a shorthand SQL statement that automatically selects ipaddr from the ipinterface table. You are basically building the WHERE clause with the rule that you write. There is an XML file called database-schema.xml in the /opt/opennms/etc directory that informs the filter code of what tables it can use in building the WHERE clause. Here is an explaination of that file:
Each table used by the filter code is in a <table> tag. If a table has an attribute of 'visible=false' then no columns in that table can be used in the WHERE clause and thus can't appear in the rule. You will get some sort of syntax exception if it sees any non-visible columns in the rule. The same applies to a non-visible column in a table.
A <join> tag tells the filter module how to relate this table to the ipinterface table. The ipinterface table is marked with the attribute 'key=primary', meaning that it is going to be the table we select ipaddr from and join all other tables to.
In brief, you can use C / Java-style comparison operators to data types they apply to ( == and != can be used on strings, as can the SQL LIKE keyword).
For LIKE comparisons, the character _ matches any single character and % matches any series of characters (or none at all). For example, 'F_o%' matches 'Foo', 'Foom' and 'Flowers' but not 'Foip'.
For handling NULL values (which includes cases where you've joined across to a table where there is no matching row), the IS NULL and IS NOT NULL operators can be used. It's important to note that comparing a null value to anything with any other operator always returns false, so
categoryName != 'SomeCategory'
will not return you anything with a null categoryName. Instead you probably need to use
categoryName != 'SomeCategory' | categoryName IS NULL
You can group expressions using parentheses and apply boolean operators anywhere in an expression. Note that, in a departure from C / Java convention, boolean operators are single characters rather than double, so they look more like the bitwise arithmetic operators in C:
Each comparision is joined together with the & or | operators meaning logical AND, logical OR operations. Anything delimited by an & or | character gets translated into a sub-select that selects the ipaddr based on the comparision for that clause.
Note: Depending on the format you use in your rules, you might need to escape your AND operator. See #The_different_rule_formats here under.
Here is an example:
(nodesysname == 'something') & (snmpifdescr == 'something else')
SELECT ipaddr FROM ipinterface WHERE ipaddr in (SELECT ipaddr FROM ipinterface, node WHERE nodesysname='something' AND ipinterface.nodeid =node.nodeid) AND ipaddr in (SELECT ipaddr FROM ipinterface, snmpInterface WHERE snmpifdescr='something else' AND ipinterface.ipaddr = snmpInterface.ipaddr);
The IPLIKE function is a short hand to call a Postgres function that was written in C to compare ipaddresses using *, lists and ranges. is<Service> is a shorthand to build a complicated join to match on a service name. notis<Service> can be used since 1.2.7 or so.
Components of openNMS that use filters
- Notification rules control whether or not a received event triggers a notification. Each event is tested against the rules in notifications.xml looking for a match. When a match is found, the corresponding notification is sent. The default for most notifications is "IPADDR IPLIKE *.*.*.*", however, any valid rule may be used. To do an exclusive filter use "!(IPADDR IPLIKE 169.254.*.*)". This allows you to be very granular when defining what to alert on.
- Controls which IP interfaces are included in a collection package. Evaluated at startup.
- Controls which IP interfaces are included in a polling package. Evaluated at startup.
- Controls which IP interfaces are included in the various categories that are shown on the front page in the webUI. Evaluated at startup and when a "uei.opennms.org/nodes/assetInfoChanged" event is received (usually generated when asset information is changed in the webUI).
- Controls which IP interfaces are included in a thresholding package. Evaluated at startup.
- The webUI uses filters to validate rules when configuring notifications. This insures that the rule will be syntactically correct, and it allows the administrator to preview the list of matching interfaces before finalizing the notification.
- Filters are also used with rules when configuring path outages to select a list of nodes that lie behind the specified outage path. This list may be previewed before finalizing the configuration.
List of possible parameters
Here is a partial list of the possible rule parameters. Parameters not present in database-schema.xml can be added for use in filter expressions, as long as the existing database table hierarchy is followed.
- Surveillance categories
- name - This field is used for alerting on user defined Applications, that span multiple systems and services.
- SNMP Interface
- snmpIfAlias (from 1.6.6 and 1.7.4)
- Server Map
- Service Map
The different rule formats
There are at least two formats which these rules can exist on the xml level (GUI format to follow).
In this first example, the entire rule is wrapped in "<![CDATA[...]]>" so that ampersands ("&") do not have to be escaped (the CDATA bits are in bold and in blue):
<rule><![CDATA[(IPADDR != '0.0.0.0') & (IPADDR IPLIKE 192.168.1.1-154) & (isSMTP | isPOP3 ) & (categoryName == 'Production')]]></rule>
In this example, instead of using the CDATA construct above, the ampersands are escaped as "&" (in bold and in blue):
<rule>(IPADDR != '0.0.0.0' & (IPADDR IPLIKE 192.168.1.1-154) & (isSMTP | isPOP3 ) & (categoryName == 'Production'))</rule>
For the GUI you simply drop in the unescaped value into the text field:
(IPADDR != '0.0.0.0' & (IPADDR IPLIKE 192.168.1.1-154) & (isSMTP | isPOP3 ) & (categoryName == 'Production'))
Sometimes you need to include hosts belonging to more than one Category, via an AND operator. eg. All hosts that belong to BOTH Production and Linux groups need to be included. It is not currently possible to do this using any variation of eg. (categoryName == 'Production') & (categoryName == 'Linux').
The "catinc" function is used the following way. Note Category names can not have spaces for this to work:
<rule> <![CDATA[((IPADDR != '0.0.0.0') & catincProduction & catincLinux)]]> </rule>