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.