00c53652c9
Replace pithy comment with something more neutral. Thanks Gordon Rowell <gordonr@gormand.com.au> r548@jpeacock: jpeacock | 2005-07-02 07:24:21 -0400 Example patterns for badrcptto plugin - Gordon Rowell <gordonr@gormand.com.au> r586@jpeacock: jpeacock | 2005-07-09 06:54:47 -0400 Don't use varlog() directly unless you are passing all parameters. Don't try to log() anything during loading of logging plugins. r587@jpeacock: jpeacock | 2005-07-09 06:59:57 -0400 Cannot use new-style hooking with logging plugins (yet). git-svn-id: https://svn.perl.org/qpsmtpd/trunk@490 958fd67b-6ff1-0310-b445-bb7760255be9
192 lines
5.4 KiB
Perl
192 lines
5.4 KiB
Perl
#!/usr/bin/perl
|
|
# Adaptive logging plugin - logs at one level for successful messages and
|
|
# one level for DENY'd messages
|
|
|
|
sub register {
|
|
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;
|
|
}
|
|
|
|
$self->register_hook( 'logging', 'wlog' );
|
|
$self->register_hook( 'deny', 'dlog' );
|
|
$self->register_hook( 'reset_transaction', 'slog' );
|
|
|
|
# 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' );
|
|
}
|
|
|
|
sub wlog {
|
|
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;
|
|
|
|
if ( $trace <= $self->{_maxlevel} ) {
|
|
warn join(
|
|
" ", $$.
|
|
(
|
|
defined $plugin ? " $plugin plugin:"
|
|
: defined $hook ? " running plugin ($hook):"
|
|
: ""
|
|
),
|
|
@log
|
|
),
|
|
"\n"
|
|
unless $log[0] =~ /logging::adaptive/;
|
|
push @{ $transaction->{_log} }, [ $trace, $hook, $plugin, @log ]
|
|
if ( $trace <= $self->{_minlevel} );
|
|
}
|
|
|
|
return DECLINED;
|
|
}
|
|
|
|
sub dlog {
|
|
my ( $self, $transaction, $prev_hook, $return, $return_text ) = @_;
|
|
$self->{_denied} = 1;
|
|
}
|
|
|
|
sub slog {
|
|
|
|
# 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;
|
|
}
|
|
|
|
=cut
|
|
|
|
|
|
=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
|
|
log lines from a accepted message will be prefixed with the character
|
|
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
|
|
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
|
|
|
|
=back
|
|
|
|
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.
|
|
|
|
=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
|
|
|