#!/usr/bin/perl -w # -*- perl -*- =head1 NAME postfix_maildeliver - Plugin to monitor the delivered 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 $spampos = undef; my $num_clean = 0; my $num_infected = 0; my $num_spam = 0; my $LOGDIR = $ENV{'logdir'} || '/var/log'; my $LOGFILE = $ENV{'logfile'} || 'syslog'; my $LOGSPAM = $ENV{'logdspam'} || '/var/lib/dspam/system.log'; sub parseLogfile { my ($fname, $start) = @_; my ($LOGFILE,$rotated) = tail_open($fname,$start); while ( <$LOGFILE> ) { if ( / dovecot: lda/ && /Spam/ ) { $num_spam++; } elsif ( / dovecot: lda/ && /discard action/ ) { $num_spam++; } elsif ( / clamav-milter/ && /Clean message/ ) { $num_clean++; } elsif ( / clamav-milter/ && /infected/ ) { $num_infected++; } } return tail_close($LOGFILE); } sub parseSpam { my ($fname, $start) = @_; my ($LOGFILE,$rotated) = tail_open($fname,$start); while ( <$LOGFILE> ) { # Note: Auto-Whitelisted etc are good, but there is no counter to use. if ( /Quarantined/ ) { $num_spam++; $num_clean--; # Spam was tested clean by clamsmtpd } } 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 Deliveries\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 "clean.label Clean\n"; print "clean.type DERIVE\n"; print "clean.min 0\n"; print "infected.label Infected\n"; print "infected.type DERIVE\n"; print "infected.min 0\n"; print "spam.label Spam\n"; print "spam.type DERIVE\n"; print "spam.min 0\n"; exit 0; } my $logfile = "$LOGDIR/$LOGFILE"; my $logspam = "$LOGSPAM"; if (! -f $logfile) { print "clean.value U\n"; print "infexted.value U\n"; print "spam.value U\n"; exit 1; } ($postpos,$spampos) = restore_state(); if (!defined($spampos)) { # 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 $spampos = (stat $logspam)[7]; $num_clean = 0; $num_infected = 0; $num_spam = 0; } else { $postpos = parseLogfile ($logfile, $postpos); $spampos = parseSpam ($logspam, $spampos); } print "clean.value $num_clean\n"; print "infected.value $num_infected\n"; print "spam.value $num_spam\n"; save_state($postpos,$spampos); # vim:syntax=perl