Writing Rules

A rules file is simply a small perl program (using helper functions) that gets loaded by LooperNG. The path to the rules file is specified by the rulesfile token in the LooperNG configuration file, or set in the administrative interface with the rules command.

rules
Syntax: rules [path|norules]

rules /opt/local/looper/conf/rules/easy.rules

rules
Rules File = /opt/local/looper/conf/rules/easy.rules
Syntax: rules [path|norules]

Type rules with no parameters to see the name of the current rules file. Or type rules norules to disable the rules file.

A basic rules file

So here's a basic rules file:

%OUT = ();

if ( $IN{__module} eq 'syslog_in1' )
{
  LOG (4, "Got syslog message...");

  $OUT{message} = "Alert on host $IN{node}: $IN{desc}";

  SEND ('logfile_out1');
}

We begin the rules file by setting emptying the %OUT hash. %OUT should contain the tokens that get sent to an output module. When a rules file is started the contents of %OUT is a copy of %IN.

So what's %IN. The %IN hash contains the tokens sent from an input module. The name of the module is set in $IN{__module}. In the above case, the syslog_in module sets $IN{node} to the hostname of the alert source and $IN{desc} to the message string.

Our rules file first checks to see where the alert came from. If it came from syslog_in1, it sets $OUT{message} and sends the event to logfile_out1. Why message? Because the logfile_out module does not care about what tokens it receives. It takes all the tokens in the %OUT hash and and logs them to the file. If we were sending the event to, say, an snmptrap_out module, we would have to set specific tokens like %OUT{enterprise} and %OUT{specifictrap}.

The SEND() command, as the name implies, is used to send an alert to an output module. SEND can be called as many times as needed in a rules file. Send takes a module name as a parameter, and feeds the contents of %OUT to the module.

Plugging it in

Assuming we started LooperNG with the configuration we built in ?Using a configuration file. We can proceed with plugging this rules file in as so:

[looperng@grok looper]$ telnet localhost 5400
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

LooperNG 1.0 running with PID 3768
Listening on grok:5400

ready
auth buggeroff
Password Accepted.

rules /opt/local/looper/conf/rules/easy.rules

stop syslog_in1
Syntax: stop TID

stop 2
Stopping syslog_in1(2).

start syslog_in1
Starting syslog_in1.

As you can see above, we set the rules file with the rules command. We really didn't have to restart syslog_in1 but it was the easiest way (apart from logger) to generate some new events (Remember that syslog_in1 is configured to read the last 10 lines of the Syslog file, hence generating events).

If you now go and examine /opt/local/looper/log/easy.out (the file which logfile_out1 writes to). You should see lines like this at the end:

Event at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: netfs: Mounting other filesystems:  succeededEvent at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: apmd[867]: Normal Resume after 09:06:17 (98% unknown) AC power
Event at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: su(pam_unix)[24842]: session opened for user root by (uid=500)
Event at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: su(pam_unix)[24842]: session closed for user root
Event at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: su(pam_unix)[25115]: session opened for user root by (uid=500)
Event at [Sat Sep 13 17:46:30 2003]
message = Alert on host localhost: syslogd 1.4.1: restart.

If you had LooperNG running in debug mode, you should see lines like this in it's log file (or on the console):

[Sat Sep 13 17:46:30 2003] [looperng] [4] process_command: [syslog_in1] go
[Sat Sep 13 17:46:30 2003] [looperng] [4] user_rules: syslog_in1
[Sat Sep 13 17:46:30 2003] [looperng] [4] Got syslog message...
[Sat Sep 13 17:46:30 2003] [looperng] [4] SEND: logfile_out1
[Sat Sep 13 17:46:30 2003] [looperng] [4] output_event: logfile_out1
[Sat Sep 13 17:46:30 2003] [looperng] [4] got_module_data: [syslog_in1] date=Aug 31 04:02:30
[Sat Sep 13 17:46:30 2003] [looperng] [4] got_module_data: [syslog_in1] node=localhost
[Sat Sep 13 17:46:30 2003] [looperng] [4] got_module_data: [syslog_in1] desc=syslogd 1.4.1: restart.
[Sat Sep 13 17:46:30 2003] [looperng] [4] got_module_data: [syslog_in1] #::go
[Sat Sep 13 17:46:30 2003] [looperng] [4] COMMAND: [syslog_in1] go
[Sat Sep 13 17:46:30 2003] [looperng] [4] process_command: [syslog_in1] go
[Sat Sep 13 17:46:30 2003] [looperng] [4] user_rules: syslog_in1
[Sat Sep 13 17:46:30 2003] [looperng] [4] Got syslog message...
[Sat Sep 13 17:46:30 2003] [looperng] [4] SEND: logfile_out1
[Sat Sep 13 17:46:30 2003] [looperng] [4] output_event: logfile_out1

You may recognize one of the lines as generated by the LOG() command in the rules file. LOG() takes two parameters: level (log level) and message (plain text string).

Other Hashes

The %SESSION hash can be used to store variables that are persistant throughout a LooperNG session. E.g.:

if (!$SESSION{FirstRun}) {
  LOG (4, "First run...");
  $SESSION{FirstRun} = 1;
  # Initialize something...

  # Load customer information...

  open (F, "/some/file");

  while (<F>) {
    chomp;
    my ($ip, $location) = split;
    $SESSION{ServerList}{$ip} = $location;
  }

  close F;
}

# do something

my $serverip = $IN{node};

if ( $SESSION{ServerList}{$serverip} eq "Toronto" ) {

  # Send all Toronto alerts to NNM server

  %OUT{...} = ...;

  LOG (4, "Sending trap...");
  SEND ('snmp_nnm1');
}

In the above code, the server location table is loaded only once and retained through the life of the LooperNG process. When LooperNG begins, the %SESSION hash is empty. It can be reinitialized as so:

%SESSION = ();

In some cases, you would want to reinitialize the %SESSION hash while LooperNG is running. To do this, send the clear session command to LooperNG on the admin interface.


Back to LooperNg Tutorial


PHP Warnings

lib/pear/DB/common.php:741: Notice[8]: Only variable references should be returned by reference

lib/pear/DB/common.php:741: Notice[8]: Only variable references should be returned by reference

lib/pear/DB/common.php:741: Notice[8]: Only variable references should be returned by reference

lib/pear/DB/common.php:741: Notice[8]: Only variable references should be returned by reference

lib/Template.php:106: Notice[8]: Only variables should be assigned by reference

lib/Template.php:107: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'htmldump'?):106: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'htmldump'?):107: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):106: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):107: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):106: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):107: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):106: Notice[8]: Only variables should be assigned by reference

lib/Template.php(In template 'body'?)(In template 'htmldump'?):107: Notice[8]: Only variables should be assigned by reference