2005-07-10 12:56:55 +02:00
|
|
|
#!perl
|
2005-03-29 22:15:53 +02:00
|
|
|
# Adaptive logging plugin - logs at one level for successful messages and
|
|
|
|
# one level for DENY'd messages
|
|
|
|
|
|
|
|
sub register {
|
2005-06-22 16:42:09 +02:00
|
|
|
my ( $self, $qp, %args ) = @_;
|
|
|
|
|
|
|
|
$self->{_minlevel} = LOGERROR;
|
|
|
|
if ( defined( $args{accept} ) ) {
|
|
|
|
if ( $args{accept} =~ /^\d+$/ ) {
|
|
|
|
$self->{_minlevel} = $args{accept};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->{_minlevel} = log_level( $args{accept} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$self->{_maxlevel} = LOGWARN;
|
|
|
|
if ( defined( $args{reject} ) ) {
|
|
|
|
if ( $args{reject} =~ /^\d+$/ ) {
|
|
|
|
$self->{_maxlevel} = $args{reject};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->{_maxlevel} = log_level( $args{reject} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$self->{_prefix} = '`';
|
|
|
|
if ( defined $args{prefix} and $args{prefix} =~ /^(.+)$/ ) {
|
|
|
|
$self->{_prefix} = $1;
|
|
|
|
}
|
|
|
|
|
|
|
|
# If you want to capture this log entry with this plugin, you need to
|
|
|
|
# wait until after you register the plugin
|
|
|
|
$self->log( LOGINFO, 'Initializing logging::adaptive plugin' );
|
2005-03-29 22:15:53 +02:00
|
|
|
}
|
|
|
|
|
2005-07-10 12:56:55 +02:00
|
|
|
sub hook_logging { # wlog
|
2005-06-22 16:42:09 +02:00
|
|
|
my ( $self, $transaction, $trace, $hook, $plugin, @log ) = @_;
|
|
|
|
|
|
|
|
# Don't log your own log entries! If this is the only logging plugin
|
|
|
|
# then these lines will not be logged at all. You can safely comment
|
|
|
|
# out this line and it will not cause an infinite loop.
|
|
|
|
return DECLINED if defined $plugin and $plugin eq $self->plugin_name;
|
|
|
|
|
2005-07-10 12:56:55 +02:00
|
|
|
if ( defined $self->{_maxlevel} && $trace <= $self->{_maxlevel} ) {
|
2006-01-26 22:36:34 +01:00
|
|
|
my $fd = $self->fd();
|
2005-06-22 16:42:09 +02:00
|
|
|
warn join(
|
|
|
|
" ", $$.
|
2006-01-26 22:36:34 +01:00
|
|
|
(defined $fd ? " fd:$fd" : "") .
|
2005-06-22 16:42:09 +02:00
|
|
|
(
|
|
|
|
defined $plugin ? " $plugin plugin:"
|
|
|
|
: defined $hook ? " running plugin ($hook):"
|
|
|
|
: ""
|
|
|
|
),
|
|
|
|
@log
|
|
|
|
),
|
|
|
|
"\n"
|
|
|
|
unless $log[0] =~ /logging::adaptive/;
|
|
|
|
push @{ $transaction->{_log} }, [ $trace, $hook, $plugin, @log ]
|
2005-07-10 12:56:55 +02:00
|
|
|
if ( defined $self->{_minlevel} && $trace <= $self->{_minlevel} );
|
2005-06-22 16:42:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return DECLINED;
|
2005-03-29 22:15:53 +02:00
|
|
|
}
|
|
|
|
|
2005-07-10 12:56:55 +02:00
|
|
|
sub hook_deny { # dlog
|
2005-06-22 16:42:09 +02:00
|
|
|
my ( $self, $transaction, $prev_hook, $return, $return_text ) = @_;
|
|
|
|
$self->{_denied} = 1;
|
2005-03-29 22:15:53 +02:00
|
|
|
}
|
|
|
|
|
2005-07-10 12:56:55 +02:00
|
|
|
sub hook_reset_transaction { # slog
|
2005-06-22 16:42:09 +02:00
|
|
|
|
|
|
|
# fires when a message is accepted
|
|
|
|
my ( $self, $transaction, @args ) = @_;
|
|
|
|
|
|
|
|
return DECLINED if $self->{_denied};
|
|
|
|
|
|
|
|
foreach my $row ( @{ $transaction->{_log} } ) {
|
|
|
|
next unless scalar @$row; # skip over empty log lines
|
|
|
|
my ( $trace, $hook, $plugin, @log ) = @$row;
|
|
|
|
warn join(
|
|
|
|
" ", $$,
|
|
|
|
$self->{_prefix}.
|
|
|
|
(
|
|
|
|
defined $plugin ? " $plugin plugin:"
|
|
|
|
: defined $hook ? " running plugin ($hook):"
|
|
|
|
: ""
|
|
|
|
),
|
|
|
|
@log
|
|
|
|
),
|
|
|
|
"\n"
|
|
|
|
if ( $trace <= $self->{_minlevel} );
|
|
|
|
}
|
|
|
|
|
|
|
|
return DECLINED;
|
2005-03-29 22:15:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
2005-06-22 16:42:09 +02:00
|
|
|
|
2005-03-29 22:15:53 +02:00
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
adaptive - An adaptive logging plugin for qpsmtpd
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
A qpsmtpd plugin for logging at different levels depending on success or
|
|
|
|
failure of any given message.
|
|
|
|
|
|
|
|
=head1 INSTALL AND CONFIG
|
|
|
|
|
|
|
|
Place this plugin in the plugin/logging directory beneath the standard
|
|
|
|
qpsmtpd installation. Edit the config/logging file and add a line like
|
|
|
|
this:
|
|
|
|
|
|
|
|
logging/adaptive [accept minlevel] [reject maxlevel] [prefix char]
|
|
|
|
|
|
|
|
where the optional parameters are:
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item B<accept>
|
|
|
|
|
|
|
|
This is the level at which messages which are accepted will be logged. You
|
|
|
|
can use either the loglevel number (as shown in config.sample/loglevels) or
|
|
|
|
you can use the text form (from the same file). Typically, you would set
|
|
|
|
this to LOGERROR (4) so that the FROM and TO lines would be logged (with the
|
|
|
|
default installation). If absent, it will be set to LOGERROR (4).
|
|
|
|
|
|
|
|
=item B<reject>
|
|
|
|
|
|
|
|
This is the level which messages which are rejected for any reason will be
|
|
|
|
logged. This would typically be set as high as reasonable, to document why a
|
|
|
|
message may have been rejected. If absent, it defaults to LOGWARN (5), which
|
|
|
|
is probably not high enough for most sites.
|
|
|
|
|
|
|
|
=item B<prefix>
|
|
|
|
|
|
|
|
In order to visually distinguish the accepted from rejected lines, all
|
2005-06-22 16:42:09 +02:00
|
|
|
log lines from a accepted message will be prefixed with the character
|
2005-03-29 22:15:53 +02:00
|
|
|
listed here (directly after the PID). You can use anything you want as
|
|
|
|
a prefix, but it is recommended that it be short (preferably just a single
|
|
|
|
character) to minimize the amount of bloat in the log file. If absent, the
|
2005-06-22 16:42:09 +02:00
|
|
|
prefix defaults to the left single quote (`).
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=head1 TYPICAL USAGE
|
|
|
|
|
|
|
|
If you are using multilog to handle your logging, you can replace the system
|
|
|
|
provided log/run file with something like this:
|
|
|
|
|
|
|
|
#! /bin/sh
|
|
|
|
export LOGDIR=./main
|
|
|
|
mkdir -p $LOGDIR/failed
|
|
|
|
exec multilog t n10 \
|
|
|
|
'-*` *' $LOGDIR/detailed \
|
|
|
|
'-*' '+*` *' $LOGDIR/accepted
|
|
|
|
|
|
|
|
which will have the following effects:
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item 1. All lines will be logged into the ./mail/detailed folder
|
|
|
|
|
|
|
|
=item 2. Log lines for messages that are accepted will go to ./main/accepted
|
2005-03-29 22:15:53 +02:00
|
|
|
|
|
|
|
=back
|
|
|
|
|
2005-06-22 16:42:09 +02:00
|
|
|
You may want to use the s####### option to multilog to ensure that the log
|
|
|
|
files are large enough to maintain a proper amount of history. Depending on
|
|
|
|
your site load, it is useful to have at least a week and preferrably three
|
|
|
|
weeks of accepted messages. You can also use the n## option to have more
|
|
|
|
log history files maintained.
|
|
|
|
|
2005-03-29 22:15:53 +02:00
|
|
|
=head1 AUTHOR
|
|
|
|
|
|
|
|
John Peacock <jpeacock@cpan.org>
|
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
|
|
|
|
Copyright (c) 2005 John Peacock
|
|
|
|
|
|
|
|
This plugin is licensed under the same terms as the qpsmtpd package itself.
|
|
|
|
Please see the LICENSE file included with qpsmtpd for details.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|