munin-contrib/plugins/qpsmtpd/qpsmtpd_mailstats

121 lines
2.2 KiB
Perl
Executable File

#!/usr/bin/perl
#
# Written by Gene Cutler, February 2011
# Loosely based on postfix_mailstats
# Graphs various qpsmtpd responses (greylisting, bad recipient, bad sender, etc.)
#
# config:
# [qpsmtpd_mailstats]
# env.logfile - Full path to qpsmtpd logfile, default = '/var/log/qpsmtpd/qpsmtpd.log'
#
# Parameters understood:
#
# config (required)
# autoconf (optional - used by munin-config)
#
#
#%# family=auto
use strict;
my $LOGFILE = $ENV{'logfile'} || '/var/log/qpsmtpd/qpsmtpd.log';
my $STATEFILE= $ENV{MUNIN_PLUGSTATE} . '/qpsmtpd_mailstats.state';
my $LINE_N = 0;
my %REJECT_CODES = (
250 => '250 queued',
450 => '450 greylisted',
451 => '451 bad recipient',
501 => '501 bad sender',
503 => '503 MAIL first',
550 => '550 bad dnsbl',
554 => '554 spamtrap',
);
if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) {
do_config();
exit(0);
}
$LINE_N = get_state();
$LINE_N ||= 0;
sub get_state {
my $fh;
open $fh,$STATEFILE;
$_ = <$fh>;
close $fh;
/^(\d+)$/;
return $1;
}
sub save_state {
my $n = shift;
my $fh;
open $fh, ">$STATEFILE";
print $fh "$n\n";
close $fh;
}
do_stats($LINE_N);
sub do_stats {
my $start_at = shift;
my $fh;
my $stop_at = (stat $LOGFILE)[7];
$start_at = 0 if $stop_at < $start_at;
my %counts = ();
open $fh, $LOGFILE or die "$!: $LOGFILE";
seek $fh, $start_at, 0 if $start_at > 0;
my $where;
while (($where = tell $fh) < $stop_at) {
my $line = <$fh>;
if ($line =~ /: 250 Queued!/) {
$counts{'250'}++;
} elsif ($line =~ /: (\d+)/ and defined $REJECT_CODES{$1}) {
$counts{$1}++;
}
}
close $fh;
save_state($stop_at);
foreach my $rc (sort {$a<=>$b} keys %REJECT_CODES) {
$counts{$rc} ||= 0;
print "r$rc.value $counts{$rc}\n";
}
}
sub do_config {
my $k;
print "graph_title QPSMTPD Responses
graph_category mail
graph_args --base 1000 -l 0
graph_vlabel responses / \${graph_period}
graph_scale no
graph_period minute
graph_total Total
";
get_state();
my $type;
foreach $k (sort {$a<=>$b} keys %REJECT_CODES) {
print
"r$k.label $REJECT_CODES{$k}
r$k.type ABSOLUTE
r$k.min 0
r$k.draw AREASTACK
";
}
};
# vim:syntax=perl