2
0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00
contrib-munin/plugins/postfix/postfix_mailvolume_multi
Clemens Schwaighofer a2c35ad7c2 Postfix monitoring plugins to work with multiple postfix installs
If there are more than one postfix running, with separate config file,
and still use the same main log file, this scripts can create stats
split per running postfix instance.

Those scripts have not been tested on the new debian multiple postfix
infrastructure, only on real separate running postfix services.

Except postfix_mailvolume_multi, each plugin needs to be configured per
running postfix.

For mailqueue* it is the config folder name, for mailstats it is the
syslog_name in the config file.

mailvolume is also based on the syslog_name, but can do auto config if
nothing has been set.
2012-03-14 12:43:50 +09:00

221 lines
4.4 KiB
Perl
Executable File

#!/usr/bin/perl -w
# -*- perl -*-
=head1 NAME
postfix_mailvolume - Plugin to monitor the volume of mails delivered
by multiple postfix and stores per postfix delivered data.
=head1 APPLICABLE SYSTEMS
Any postfix.
=head1 CONFIGURATION
The following shows the default configuration.
[postfix*]
env.logdir /var/log
env.logfile syslog
=head2 Needed additional configuration
To correctly get all the postfix log data, the postfix system_log prefix names need to be defined with the env.postfix config setting.
If this is not set, the script tries to find all the postfix config folders in /etc/postfix* and get the syslog names from there
env.postfix postfix10 postfix11 postfix12
=head1 INTERPRETATION
The plugin shows the number of bytes of mail that has passed through
the postfix installation per postfix mailer running.
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 BUGS
None known
=head1 VERSION
$Id: postfix_mailvolume.in 2314 2009-08-03 11:28:34Z ssm $
=head1 AUTHOR
Copyright (C) 2011.
Clemens Schwaighofer (gullevek@gullevek.org)
=head1 LICENSE
GPLv2
=cut
use strict;
use Munin::Plugin;
my $pos = undef;
my $syslog_name = '';
my @postfix_syslog_name = ();
my %volume = ();
my @restore_state = ();
my $i = 1;
my $LOGDIR = $ENV{'logdir'} || '/var/log';
my $LOGFILE = $ENV{'logfile'} || 'syslog';
my $POSTFIX = $ENV{'postfix'} || '';
# get the postfix syslog_name from the POSTFIX env var, if not set, find them in the /etc/postfix* type
if (!$POSTFIX)
{
foreach my $dir (grep -d, glob "/etc/postfix*")
{
# remove the leading etc
$dir =~ s/\/etc\///g;
# add data to the postfix string
$POSTFIX .= ' ' if ($POSTFIX);
$POSTFIX .= $dir;
}
}
if ($POSTFIX)
{
foreach my $config (split(/ /, $POSTFIX))
{
# find the syslog name
$syslog_name = `postconf -c /etc/$config | grep "syslog_name"`;
# remove any pending whitespace or line breaks
chomp($syslog_name);
$syslog_name =~ s/syslog_name = //g;
# add this to the postfix syslog name array
push(@postfix_syslog_name, $syslog_name);
# also init set the syslog name 0
$volume{$syslog_name} = 0;
}
}
else
{
print "Cannot get any postfix syslog_name data\n";
exit 1;
}
sub parseLogfile
{
my ($fname, $start) = @_;
my ($LOGFILE, $rotated) = tail_open($fname, $start);
my $line;
while ($line =<$LOGFILE>)
{
chomp ($line);
# get the postfix syslog name and the size
if ($line =~ /\ (\w+)\/qmgr.*from=.*size=([0-9]+)/)
{
$volume{$1} += $2;
}
}
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 bytes throughput per postfix\n";
print "graph_args --base 1000 -l 0\n";
print "graph_vlabel bytes / \${graph_period}\n";
print "graph_scale yes\n";
print "graph_category postfix\n";
print "graph_total Throughput sum\n";
# loop through the postfix names and create per config an entry
foreach $syslog_name (@postfix_syslog_name)
{
print $syslog_name."_volume.label ".$syslog_name." throughput\n";
print $syslog_name."_volume.type DERIVE\n";
print $syslog_name."_volume.min 0\n";
}
exit 0;
}
my $logfile = "$LOGDIR/$LOGFILE";
if (! -f $logfile) {
print "delivered.value U\n";
exit 1;
}
@restore_state = restore_state();
# first is pos, rest is postfix entries
$pos = $restore_state[0];
# per postfix values are store: postfix config,value
for ($i = 1; $i < @restore_state; $i ++)
{
my ($key, $value) = split(/,/, $restore_state[$i]);
$volume{$key} = $value;
}
if (!$pos)
{
# 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.
$pos = (stat $logfile)[7]; # File size
foreach $syslog_name (@postfix_syslog_name)
{
$volume{$syslog_name} = 0;
}
}
else
{
$pos = parseLogfile($logfile, $pos);
}
@restore_state = ($pos);
foreach $syslog_name (sort keys %volume)
{
print $syslog_name."_volume.value ".$volume{$syslog_name}."\n";
push(@restore_state, $syslog_name.','.$volume{$syslog_name});
}
# save the current state
save_state(@restore_state);
# vim:syntax=perl
__END__