NAME

SyslogScan::Daemon - Watch log files

SYNOPSIS

syslogscand [-f] [-c config] {start|stop|reload|restart|check}

@ISA = qw(SyslogScan::Daemon);

newdaemon()

DESCRIPTION

SyslogScan::Daemon is a framework on which to hang log file watchers. SyslogScan::Daemon is a subclass of Daemon::Generic and uses Plugins to create the framework.

CONFIGURATION PREFIX

The configuration prefix for plugins for SyslogScan::Daemon is ''. Use "plugin" to load plugins.

CONFIGURATION PARAMETERS

SyslogScan::Daemon defines the following configuration parameters which may be given in indented lines that follow "plugin SyslogScan::Daemon" or anywhere in the configuration file.

debug (default 0) Turn on debugging.

    configfile     (default "/etc/syslogscand.conf"). The location of the
                   configuration file for the plugins or SyslogScan::Daemon.

WRITING PLUGINS

Plugins for SyslogScan::Daemon should subclass SyslogScan::Daemon::Plugin. The following methods will be invoked by SyslogScan::Daemon:

    new(%args)     Called from Plugins and %args will come from the
                   configuration file. An object of the type of the plugin
                   is expected as the return value. It's okay to "die" here.

preconfig($configfile)

                   Called right after "new()" and when a "reload" is
                   requested. Return value is a %hash that is then passed
                   into "postconfig()". It's okay to "die" here.

postconfig(%args)

                   Called after all plugin's "preconfig()"s are called. No
                   return value is expected.

    get_logs()     Called after "postconfig()". The return value of
                   "get_logs()" is a hash: the keys are log file names and
                   the values are lists of regular expressions to match. For
                   example:

                    sub get_logs
                    {
                           return (
                                   '/var/log/mail.log'     => [
                                           qr{postfix/smtp\[\d+\]: \w+: to=<([^@]+@([^>]+))>, ., status=(bounced).\b(?i:blacklist(ed)?|spamming|spam list|removal|remove|block list|blocked for abuse)\b},
                                           qr{postfix/smtp\[\d+\]: \w+: to=<([^@]+@([^>]+))>, ., status=(deferred).Rejected: \S+ listed at http},
                                   ],
                           );
                    }

                   The default implementation of "get_logs()" checks to see
                   if there is a "$self-"{plugins}> member and if there is,
                   it re-dispatches the "get_logs()" call to its plugins. It
                   keeps track of the regular expressions returned by its
                   plugins that in "matched_line()", callbacks can be
                   redistributed to the appropriate plugin:

                    sub matched_line
                    {
                           my ($self, $logfile, $rx) = @_;

                           for my $plugin (@{$self->{logs}{$logfile}{$rx}}) {
                                   my @ret = $plugin->invoke('parse_logs', $logfile, $rx);

                                   # your stuff here...
                           }
                    }

matched_line($file, $rx)

                   Called after one of the regular expressions returned by
                   "get_logs()" matched a log line. The arguments are the
                   log filename where the match was found and the regular
                   expression that matched. Passed implicitly are the line
                   that was matched ($_) and any of the numbered regular
                   expression submatches ($1, $2, etc). No return value is
                   expected.

    periodic()     Called once per second or so (or however of the config
                   file says).

                   The default implementation of "periodic()" checks to see
                   if there is a "$self-"{plugins}> member and if there is
                   calls "$self-"{plugins}->invoke('periodic')> to send the
                   heartbeat down the plugin tree.

Use Plugins::SimpleConfig
Using Plugins::SimpleConfig to write the plugins make the job much easier.

Plugins that have plugins
For plugins that in turn have plugins, a helper function is provided in SyslogScan::Daemon::Plugin:

     sub set_api
     {
            my ($self, $ssd_configfile, @api) = @_;

            my $config = $self->{configfile} || $ssd_configfile;

            $self->{myapi} = Plugins::API->new;
            $self->{myapi}->api(@api);
            $self->{myapi}->autoregister($self);
            $self->{myapi}->register(undef, parentapi => sub { return $self->{api} });

            $self->{plugins} = new Plugins context => $self->{context};
            $self->{plugins}->readconfig($config, self => $self);

            $self->{plugins}->api($self->{myapi});
            $self->{myapi}->plugins($self->{plugins});

            $self->{plugins}->initialize();
            $self->{plugins}->invoke('preconfig', $config);
     }

To use it, define your "preconfig()" as follows:

     sub preconfig
     {
            my ($self, $ssd_configfile, @api) = @_;

            $self->set_api($ssd_configfile,
                    stuff for Plugins::API::api()
            );

            ... more initialization if needed
     }

SEE ALSO

Plugins Plugins::Style1 Plugins::API SyslogScan::Daemon::BlacklistDetector SyslogScan::Daemon::SpamDetector

LICENSE

Copyright (C) 2006, David Muir Sharnoff <muir@idiom.com> This module may be used and copied on the same basis as Perl itself.

If you find this useful, please thank me by giving me a chance to bid on your next Internet transit purchase of T1 or larger. I have good prices for T1s, T3s, OC3s and such. Thank you.