opEvents can process information from a variety of sources, some of which can be extended to suit non-standard deployments. This document briefly documents how to configure opEvents' input sources.

Input Configuration

The inputs opEvents is supposed to handle are specified in the opevents section of conf/opCommon.nmis, primarily in subsection opevents_logs. opEvents primarily handles event information sourced by consuming and collating log files from sources like NMIS, Tivoli or general syslogs.

Here is an example configuration fragment:

 'opevents_logs' => {
  # parsertype => list of logfiles (or dirs for nmis_json_dir)
  # natively supported: tivoli_log, cisco_syslog, nmis_traplog, 
  # nmis_eventlog, nmis_slavelog and nmis_json_dir
  'cisco_syslog' => [ '<nmis_logs>/cisco.log', "/some/other/log.file" ],
  'tivoli_log' => [ '<nmis_logs>/tivoli.log' ],
  'nmis_traplog' => [ '<nmis_logs>/trap.log' ],
  'nmis_slavelog' => [ '<nmis_logs>/slave_event.log' ],
  'nmis_eventlog' => [ '<nmis_logs>/event.log' ],
  # attention: json logs in this directory are REMOVED after consumption
  # 'nmis_json_dir' => [ '<nmis_logs>/json' ],
 },

The natively understood formats are:

Format NameDescription
nmis_eventlogAn event log file created by NMIS
nmis_slavelogAn NMIS slave log file
nmis_traplogAn NMIS trap log file
nmis_json_dirA directory of NMIS event logs in JSON format
cisco_syslogA Syslog log file containing logs created by Cisco devices
tivoli_log

A Tivoli log file

To enable a particular log file or format, you need to add an entry for the  log file in question to the list of files for the appropriate log format; check the  cisco_syslog entry in the example above for the syntax. The tokens <nmis_something> in the example work like centrally-defined shortcuts or macros; they are replaced by the actual locations given in the directories section at the beginning of conf/opCommon.nmis.

opEvents handles non-existent log files gracefully, but the log formats need to match the actual content. All log files are reopened on demand (e.g. when log rotation renames a file), and checked at least once every opeventsd_update_rate seconds. The order of log file specifications is not relevant. 

Black and Whitelisting

opEvents ships with ready-made black and whitelist rules to reduce voluminous inputs down to the relevant details, but these can be adjusted at need. These lists are active if the settings  black_list_enabled or white_list_enabled are set to true, respectively.

The black list contains a set of filtering rules which remove matching log entries from opEvents' input stream. The white list rules can be used to ensure that matching input entries are processed; if the white list is enabled, then only events matching the white list will be processed (but raw logging is still performed for forensics purposes). Enabling both black and white list options simultaneously is not useful.

Both black and white lists are configured in conf/EventListRules.nmis, in sections like this example:

'blackList' => { 
 '10' => 'NTP Core \(INFO\)',
 '20' => 'OLD-CISCO-TS-MIB::tslineSesType\.6\.1=tcp',
 '30' => 'CISCO-SYSLOG-MIB::clogMessageGenerated',
 },
'whiteList' => {
 '1' => 'TIVOLI\|\w+\|ams',
 '10' => 'SYS-[0123]-\w+',
 '20' => 'LINEPROTO',
 '30' => 'OSPF-\d-ADJCHG',
...

The format is straight-forward: the numeric key controls order of rule application, and the right side is a regular expression that the log entries are matched against.

Normalisation and Enrichment

For the natively-supported log formats (except nmis_json_dir) only the actual parsing is hard-coded; the act of subsequent further extraction and collection of relevant details is configurable - but of course opEvents ships with a substantial set of default normalisation rules. Event normalisation consists of associating a log entry with a node, extracting details, determining whether the event is stateful or stateless, followed by optional additional enrichment from external sources.

Normalisation is controlled by the configuration files conf/EventSyslogRules.nmis, EventNmisRules.nmisEventTivoliRules.nmis and EventTrapRules.nmis, all of which have a similar format. Here is an example config fragment from the syslog rules:

'rules' => {
 '1' => {
	 event => 'Interface Down',
	 regex => qr/LINEPROTO-5-UPDOWN:.+down/,
	 stateful => 'Interface',
	 priority => 1,
 },
 ...
 '10' => {
 	 regex => qr/Interface (\w+[\d\/\.]+)/,
 	 name => 'element',
 },

The key component is the rules section, which controls what details are extracted from a log entry and how they are saved a sevent properties. There are a few ways of augmenting the event with information:

(You might also encounter the deprecated legacy format of using directives name and value to set just one property to a fixed value.)

In the example above, rule 1 will be active if a "line protocol down" log entry is detected, and in that case it'll add properties "priority", "event", and "stateful", all with static values. Rule 10 will be active if the log entry contains "Interface <something>", and it'll copy over the matched <something> as the value of the property named "event".

All normalisation rules are checked in sequence of their numeric key, and all the ones whose regex directive matches will contribute to the new event's properties. Normalisation and enrichment then continues using information from NMIS; events are associated with the relevant nodes, stateful deduplication is performed etc.

Further enrichment can be performed using policy actions (using the tag.tagname() action), enrichment statements in correlation rules or from external databases.

Please note that the log file format nmis_json_dir is not subject to normalisation; instead the contents of these are expected to be normalised already.

Command-line Event Creation

To provide a simple interface for external programs, opEvents also can create an event "on the fly" with event details from command-line arguments or a JSON file.

To create an event on the fly, you have to call opeventsd.pl with the argument act=create-event, which causes it to use all further key=value pairs in the arguments to construct an event, like this example:

opeventsd.pl act=create-event event=testevent node="somenode" details="this is just a test event" action_required=1 action_checked=0 priority=4

Your event is expected to contain all required event properties and no further normalisation is performed.  The option action_required should be set to 1 so that opEvents will process the event with Action Policies, or 0 to have opEvents not process with action policies.

Alternatively you can save your desired event's properties in a file in JSON format, and use act=create-json to instruct opeventsd to create an event from it:

opeventsd.pl act=create-json path=./myevent_in_format.json

Generic Extensible Parser

In situations where none of the built-in input mechanisms are suitable you can also define your own generic parser rules to integrate just about any text-based log information into opEvents.

The generic parser is activated by the configuration option opevents_parser_rules, in conf/opCommon.nmis, and the rules are defined in conf/EventParserRules.nmis. Hiere is an excerpt from the generic parser rules example that opEvents ships with:

'cisco_alternate' => {
 1 => {
 	"IF" => qr/%/, # no cisco log if no % present
 	"THEN" => {
 		  # match date/time, host and details
		  10 => {
			 IF => qr/^(\S+\s+\d+\s+[\d:]+)\s+(\S+)[^%]+%(.+)$/,
			 THEN => "capture(date,host,details)",
		  },
		  # some units have Local instead of hms
		 11 => {
			 IF => qr/^(\S+\s+\d+)\s+Local\s+(\S+)[^%]+%(.+)$/,
			 THEN => "capture(date,host,details)",
		 },
		 # match event name, could have done that in one of the regexp above
		 20 => {
			 IF => qr/%(\w+\-\d-\w+):/,
			 THEN => "capture(event) AND capture(syslog)", # save this in two places
		 },
 		 '23' => {
			 IF => qr/%BGP-5-ADJCHANGE: neighbor (\d+\.\d+\.\d+\.\d+) Down/,
			 THEN => 'capture(element) AND set.event(BGP Neighbor Down) AND set.state(down) AND set.priority(4) AND set.stateful(BGP Neighbor)',
 		 },
...

The format is straight-forward: the top key allocates a new log format type (here cisco_alternate) which you would use in opevents_logs for your log files. Under that key there are any number of (nested) capture rules, which control what to match in an input, and how to copy material to the newly created event. These rules use a format very similar to the Event Actions and Escalation policies: IF defines a regular expression that the log entry has to match, THEN declares what to do in that case, and a successful rule with optional BREAK statement skips the rules on the same nesting level.

The THEN expression consists of a nested sub-policy or of a single action statement. The action statement is an AND-separated list of action statements: 

Rules are applied in the order defined by their numeric key, and nesting is fully supported.