Révision df677670
Initial version
| plugins/other/qpsmtpd_mailstats | ||
|---|---|---|
| 1 |
#!/usr/bin/perl |
|
| 2 |
# |
|
| 3 |
# Written by Gene Cutler, February 2011 |
|
| 4 |
# Loosely based on postfix_mailstats |
|
| 5 |
# Graphs various qpsmtpd responses (greylisting, bad recipient, bad sender, etc.) |
|
| 6 |
# |
|
| 7 |
# config: |
|
| 8 |
# [qpsmtpd_mailstats] |
|
| 9 |
# env.logfile - Full path to qpsmtpd logfile, default = '/var/log/qpsmtpd/qpsmtpd.log' |
|
| 10 |
# |
|
| 11 |
# Parameters understood: |
|
| 12 |
# |
|
| 13 |
# config (required) |
|
| 14 |
# autoconf (optional - used by munin-config) |
|
| 15 |
# |
|
| 16 |
# |
|
| 17 |
#%# family=auto |
|
| 18 |
|
|
| 19 |
use strict; |
|
| 20 |
|
|
| 21 |
my $LOGFILE = $ENV{'logfile'} || '/var/log/qpsmtpd/qpsmtpd.log';
|
|
| 22 |
my $STATEFILE= $ENV{MUNIN_PLUGSTATE} . '/qpsmtpd_mailstats.state';
|
|
| 23 |
my $LINE_N = 0; |
|
| 24 |
my %REJECT_CODES = ( |
|
| 25 |
250 => '250 queued', |
|
| 26 |
450 => '450 greylisted', |
|
| 27 |
451 => '451 bad recipient', |
|
| 28 |
501 => '501 bad sender', |
|
| 29 |
503 => '503 MAIL first', |
|
| 30 |
550 => '550 bad dnsbl', |
|
| 31 |
554 => '554 spamtrap', |
|
| 32 |
); |
|
| 33 |
|
|
| 34 |
if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) {
|
|
| 35 |
do_config(); |
|
| 36 |
exit(0); |
|
| 37 |
} |
|
| 38 |
|
|
| 39 |
$LINE_N = get_state(); |
|
| 40 |
$LINE_N ||= 0; |
|
| 41 |
|
|
| 42 |
sub get_state {
|
|
| 43 |
my $fh; |
|
| 44 |
open $fh,$STATEFILE; |
|
| 45 |
$_ = <$fh>; |
|
| 46 |
close $fh; |
|
| 47 |
/^(\d+)$/; |
|
| 48 |
return $1; |
|
| 49 |
} |
|
| 50 |
|
|
| 51 |
sub save_state {
|
|
| 52 |
my $n = shift; |
|
| 53 |
my $fh; |
|
| 54 |
open $fh, ">$STATEFILE"; |
|
| 55 |
print $fh "$n\n"; |
|
| 56 |
close $fh; |
|
| 57 |
} |
|
| 58 |
|
|
| 59 |
|
|
| 60 |
do_stats($LINE_N); |
|
| 61 |
|
|
| 62 |
|
|
| 63 |
sub do_stats {
|
|
| 64 |
my $start_at = shift; |
|
| 65 |
my $fh; |
|
| 66 |
my $stop_at = (stat $LOGFILE)[7]; |
|
| 67 |
$start_at = 0 if $stop_at < $start_at; |
|
| 68 |
|
|
| 69 |
my %counts = (); |
|
| 70 |
|
|
| 71 |
open $fh, $LOGFILE or die "$!: $LOGFILE"; |
|
| 72 |
|
|
| 73 |
seek $fh, $start_at, 0 if $start_at > 0; |
|
| 74 |
|
|
| 75 |
my $where; |
|
| 76 |
while (($where = tell $fh) < $stop_at) {
|
|
| 77 |
my $line = <$fh>; |
|
| 78 |
if ($line =~ /: 250 Queued!/) {
|
|
| 79 |
$counts{'250'}++;
|
|
| 80 |
} elsif ($line =~ /: (\d+)/ and defined $REJECT_CODES{$1}) {
|
|
| 81 |
$counts{$1}++;
|
|
| 82 |
} |
|
| 83 |
} |
|
| 84 |
close $fh; |
|
| 85 |
|
|
| 86 |
save_state($stop_at); |
|
| 87 |
|
|
| 88 |
foreach my $rc (sort {$a<=>$b} keys %REJECT_CODES) {
|
|
| 89 |
$counts{$rc} ||= 0;
|
|
| 90 |
print "r$rc.value $counts{$rc}\n";
|
|
| 91 |
} |
|
| 92 |
} |
|
| 93 |
|
|
| 94 |
|
|
| 95 |
sub do_config {
|
|
| 96 |
my $k; |
|
| 97 |
|
|
| 98 |
print "graph_title QPSMTPD Responses |
|
| 99 |
graph_category QPSMTPD |
|
| 100 |
graph_args --base 1000 -l 0 |
|
| 101 |
graph_vlabel responses / \${graph_period}
|
|
| 102 |
graph_scale no |
|
| 103 |
graph_period minute |
|
| 104 |
graph_total Total |
|
| 105 |
"; |
|
| 106 |
|
|
| 107 |
get_state(); |
|
| 108 |
|
|
| 109 |
my $type; |
|
| 110 |
foreach $k (sort {$a<=>$b} keys %REJECT_CODES) {
|
|
| 111 |
|
|
| 112 |
"r$k.label $REJECT_CODES{$k}
|
|
| 113 |
r$k.type ABSOLUTE |
|
| 114 |
r$k.min 0 |
|
| 115 |
r$k.draw AREASTACK |
|
| 116 |
"; |
|
| 117 |
} |
|
| 118 |
}; |
|
| 119 |
|
|
| 120 |
# vim:syntax=perl |
|
Formats disponibles : Unified diff