#!/usr/bin/perl -w # -*- perl -*- =head1 NAME postfix_mailflow - Plugin to monitor the number of mails handled by postfix. =head1 APPLICABLE SYSTEMS Any postfix. =head1 CONFIGURATION The following shows the default configuration. [postfix*] env.logdir /var/log env.logfile syslog =head1 INTERPRETATION The plugin shows the number of bytes of mail that has passed through the postfix installation. =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =head1 BUGS None known =head1 AUTHOR Copyright (C) 2012 M. Broek =head1 LICENSE GPLv2 =cut use strict; use Munin::Plugin; my $postpos = undef; my $num_rec = 0; # Received my $num_sent = 0; # Sent my $num_deferred = 0; my $num_bounced = 0; my $num_reject = 0; # Rejected my $num_banned = 0; my $LOGDIR = $ENV{'logdir'} || '/var/log'; my $LOGFILE = $ENV{'logfile'} || 'syslog'; sub parseLogfile { my ($fname, $start) = @_; my ($LOGFILE,$rotated) = tail_open($fname,$start); while ( <$LOGFILE> ) { if ( /status=sent/ && /relay=local/ ) { $num_rec++; } elsif ( /status=sent/ && ! /relay=(mailfilter|procmail|local|127.0.0.1)/ ) { $num_sent++; } elsif ( /status=deferred/ ) { $num_deferred++; } elsif ( /status=bounced/ ) { $num_bounced++; } elsif ( /: NOQUEUE: reject: / ) { $num_reject++; } elsif ( /warning: non-SMTP command / ) { $num_reject++; } elsif ( / Blocked BANNED/ ) { $num_banned++; } } return tail_close($LOGFILE); } if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) { my $logfile; `which postconf >/dev/null 2>/dev/null`; if (!$?) { $logfile = "$LOGDIR/$LOGFILE"; if (-f $logfile) { if (-r "$logfile") { print "yes\n"; exit 0; } else { print "no (logfile '$logfile' not readable)\n"; } } else { print "no (logfile '$logfile' not found)\n"; } } else { print "no (postfix not found)\n"; } exit 0; } if ( $ARGV[0] and $ARGV[0] eq "config" ) { print "graph_title Postfix Mailflow\n"; print "graph_args --base 1000 -l 0\n"; print "graph_vlabel messages / \${graph_period}\n"; print "graph_scale yes\n"; print "graph_category postfix\n"; print "received.label Received\n"; print "received.type DERIVE\n"; print "received.min 0\n"; print "sent.label Sent\n"; print "sent.type DERIVE\n"; print "sent.min 0\n"; print "deferred.label Deferred\n"; print "deferred.type DERIVE\n"; print "deferred.min 0\n"; print "bounced.label Bounced\n"; print "bounced.type DERIVE\n"; print "bounced.min 0\n"; print "reject.label Rejected\n"; print "reject.type DERIVE\n"; print "reject.min 0\n"; print "banned.label Banned\n"; print "banned.type DERIVE\n"; print "banned.min 0\n"; exit 0; } my $logfile = "$LOGDIR/$LOGFILE"; if (! -f $logfile) { print "received.value U\n"; print "sent.value U\n"; print "deferred.value U\n"; print "bounced.value U\n"; print "reject.value U\n"; print "banned.value U\n"; exit 1; } ($postpos) = restore_state(); if (!defined($num_rec)) { # No state file present. Avoid startup spike: Do not read log # file up to now, but remember how large it is now, and next # time read from there. $postpos = (stat $logfile)[7]; # File size $num_rec = 0; # Received $num_sent = 0; # Sent $num_deferred = 0; $num_bounced = 0; $num_reject = 0; # Rejected $num_banned = 0; } else { $postpos = parseLogfile ($logfile, $postpos); } print "received.value $num_rec\n"; print "sent.value $num_sent\n"; print "deferred.value $num_deferred\n"; print "bounced.value $num_bounced\n"; print "reject.value $num_reject\n"; print "banned.value $num_banned\n"; save_state($postpos); # vim:syntax=perl