#!/usr/bin/perl -w ############### # CRANS ############### # La version de ce plugin dans debian Etch (<= 4.0r1) est bugguée. # En attendant on utilise donc cette version # À la mise à jour de munin, il est souhaitable de tester le fichier # original (/usr/share/munin/plugins/postfix_mailstats). ############### 20/09/2007 - Nicolas Salles # # Plugin to monitor the number of mails delivered and rejected by postfix. # # Usage: copy or link into /etc/munin/node.d/ # # Parameters: # # config (required) # autoconf (optional - used by munin-config) # # Config variables: # # logdir - Which logfile to use # logfile - What file to read in logdir # # $Log: postfix_mailstats,v $ # Revision 1.2 2007-09-20 06:47:15 salles # Un petit warning pour laisser une trace # # Revision 1.1 2007-09-20 06:45:03 salles # Ce plugin est buggué dans etch. # En attendant une mise à jour, on utilise cette version modifiée. # # Revision 1.6.2.3 2005/01/25 20:39:16 jimmyo # Make generic/postfix_mailstats catch more formats (Deb#292110). # # Revision 1.6.2.2 2005/01/25 20:24:09 jimmyo # Improved graph_title of generic/postfix_* (Deb#292083). # # Revision 1.6.2.1 2005/01/24 19:44:13 jimmyo # Changed default log for generic/postfix_mailstats from syslog to mail.log. Downgraded it from auto to manual. # # Revision 1.6 2004/12/10 18:51:43 jimmyo # linux/apt* has been forced to LANG=C, to get predictable output. # # Revision 1.5 2004/12/10 10:47:47 jimmyo # Change name from ${scale} to ${graph_period}, to be more consistent. # # Revision 1.4 2004/12/09 22:12:55 jimmyo # Added "graph_period" option, to make "graph_sums" usable. # # Revision 1.3 2004/05/20 19:02:36 jimmyo # Set categories on a bunch of plugins # # Revision 1.2 2004/05/14 21:16:46 jimmyo # "Upped" som plugins from contrib/manual to auto. # # Revision 1.1 2004/01/02 18:50:00 jimmyo # Renamed occurrances of lrrd -> munin # # Revision 1.1.1.1 2004/01/02 15:18:07 jimmyo # Import of LRRD CVS tree after renaming to Munin # # Revision 1.2 2003/11/26 14:55:52 jimmyo # Added total summaries # # Revision 1.1 2003/11/26 14:45:34 jimmyo # New plugins # # Revision 1.7 2003/11/15 11:10:28 jimmyo # Various fixes # # Revision 1.6 2003/11/07 17:43:16 jimmyo # Cleanups and log entries # # # # Magic markers (optional - used by munin-config and some installation # scripts): # #%# family=manual #%# capabilities=autoconf my $statefile = "/var/lib/munin/plugin-state/munin-plugin-postfix_mailstats.state"; my $pos = undef; my $delivered = 0; my $rejects = {}; my $LOGDIR = $ENV{'logdir'} || '/var/log'; my $LOGFILE = $ENV{'logfile'} || 'mail.log'; if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) { my $logfile; if (-d $LOGDIR) { $logfile = "$LOGDIR/$LOGFILE"; if (-f $logfile) { if (-r "$logfile") { print "yes\n"; exit 0; } else { print "no (logfile not readable)\n"; } } else { print "no (logfile not found)\n"; } } else { print "no (could not find logdir)\n"; } exit 1; } my $logfile = "$LOGDIR/$LOGFILE"; my $prevdate = get_prev_date(); if (-f "$logfile.$prevdate") { $rotlogfile = "$logfile.$prevdate"; } elsif (-f "$logfile.0") { $rotlogfile = $logfile . ".0"; } elsif (-f "$logfile.1") { $rotlogfile = $logfile . ".1"; } elsif (-f "$logfile.01") { $rotlogfile = $logfile . ".01"; } else { $rotlogfile = $logfile . ".0"; } if (-f "$statefile") { open (IN, "$statefile") or exit 4; if ( =~ /^(\d+):(\d+)/) { ($pos, $delivered) = ($1, $2); } while () { if (/^(\d+):(\d+)$/) { $rejects->{$1} = $2; } elsif (/^OTHER:(\d+)$/) { $rejects->{OTHER} = $1; } } close IN; } if (! -f $logfile and ! -f $rotlogfile) { print "delivered.value U\n"; foreach my $i (keys %{$rejects}) { print "r$i.value U\n"; } exit 0; } $startsize = (stat $logfile)[7]; if (!defined $pos) { # Initial run. $pos = $startsize; } if ($startsize < $pos) { # Log rotated parseLogfile ($rotlogfile, $pos, (stat $rotlogfile)[7]); $pos = 0; } parseLogfile ($logfile, $pos, $startsize); $pos = $startsize; if ( $ARGV[0] and $ARGV[0] eq "config" ) { print "graph_title Postfix message throughput\n"; print "graph_args --base 1000 -l 0\n"; print "graph_vlabel mails / \${graph_period}\n"; print "graph_scale no\n"; print "graph_total Total\n"; print "graph_category postfix\n"; print "delivered.label delivered\n"; print "delivered.type DERIVE\n"; print "delivered.draw AREA\n"; print "delivered.min 0\n"; foreach my $i (keys %{$rejects}) { print "r$i.label reject $i\n"; print "r$i.type DERIVE\n"; print "r$i.draw STACK\n"; print "r$i.min 0\n"; } exit 0; } print "delivered.value $delivered\n"; foreach my $i (keys %{$rejects}) { print "r$i.value ", $rejects->{$i}, "\n"; } if(-l $statefile) { die("$statefile is a symbolic link, refusing to touch it."); } open (OUT, ">$statefile") or exit 4; print OUT "$pos:$delivered\n"; foreach my $i (keys %{$rejects}) { print OUT "$i:", $rejects->{$i}, "\n"; } close OUT; sub parseLogfile { my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) or exit 3; seek (LOGFILE, $start, 0) or exit 2; while (tell (LOGFILE) < $stop) { my $line =; chomp ($line); if ($line =~ /qmgr.*from=.*size=[0-9]*/) { $delivered++; } elsif ($line =~ /postfix\/smtpd.*reject: \S+ \S+ \S+ (\S+)/) { my $cause = $1; $cause = 'OTHER' unless $1 =~/^\d+$/; $rejects->{$cause} ++; } } close(LOGFILE); } sub get_prev_date { my @date = localtime (time - 86400); my $prevdate = $date[5]+1900 . $date[4]+1 . $date[3]; return $prevdate; } # vim:syntax=perl