2013-12-25 04:30:51 +01:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
# -*- perl -*-
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
postfix_mailqueuelog_ - detailed stats for postfix queue data
|
|
|
|
|
|
|
|
=head1 CONFIGURATION
|
|
|
|
|
|
|
|
Use the last part in the symlink to define which postfix you want to get stats from.
|
|
|
|
|
|
|
|
The user has to be set as root, else there might be some errors if
|
2014-12-05 00:37:42 +01:00
|
|
|
the postfix config is not correctly set with the alternate directories
|
2013-12-25 04:30:51 +01:00
|
|
|
|
|
|
|
[postfix_mailqueuelog_*]
|
|
|
|
env.etcdir /etc/
|
|
|
|
user root
|
|
|
|
|
|
|
|
=head2 DEFAULT CONFIGURATION
|
|
|
|
|
|
|
|
[postfix_mailqueuelog_*]
|
|
|
|
user root
|
|
|
|
|
|
|
|
=head1 AUTHOR
|
|
|
|
|
|
|
|
Written in 2010 by Clemens Schwaighofer (gullevek@gullevek.org), based on the HoSaNIC module written by me
|
|
|
|
|
|
|
|
=head1 LICENSE
|
|
|
|
|
|
|
|
GPLv2
|
|
|
|
|
|
|
|
=head1 MAGIC MARKERS
|
|
|
|
|
|
|
|
=begin comment
|
|
|
|
|
|
|
|
These magic markers are used by munin-node-configure when installing
|
|
|
|
munin-node.
|
|
|
|
|
|
|
|
=end comment
|
|
|
|
|
|
|
|
#%# family=manual
|
|
|
|
#%# capabilities=autoconf
|
|
|
|
|
|
|
|
=head1 RANDOM COMMENTS
|
|
|
|
|
|
|
|
Would be cool if someone ported this to Munin::Plugin state file.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
# get the postfix queue number to look for
|
|
|
|
$0 =~ /postfix_mailqueuelog_([\w\d\-]+)$/;
|
|
|
|
my $postfix = $1;
|
|
|
|
#my $statefile = "$ENV{MUNIN_PLUGSTATE}/munin-plugin-".$postfix."_mailqueuelog.state";
|
|
|
|
my $sum = 0;
|
|
|
|
my $status = {};
|
|
|
|
my @status_list = ('crefused', 'ctimeout', 'rtimeout', 'refusedtalk', 'nohost', 'msrefused', 'noroute', 'usernotfound', 'err450', 'err452', 'err421', 'err421a', 'err4', 'lostc', 'active', 'other');
|
|
|
|
my $ETCDIR = $ENV{'etcdir'} || '/etc';
|
|
|
|
|
|
|
|
my $configdir = "$ETCDIR/$postfix/";
|
|
|
|
|
|
|
|
if ( $ARGV[0] and $ARGV[0] eq "autoconf" )
|
|
|
|
{
|
|
|
|
if (-d $ETCDIR)
|
|
|
|
{
|
|
|
|
if (-d $configdir)
|
|
|
|
{
|
|
|
|
if (-r $configdir)
|
|
|
|
{
|
|
|
|
print "yes\n";
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print "no (config dir '$configdir' not readable)\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print "no (config dir '$configdir' not found)\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print "no (could not find etcdir '$ETCDIR')\n";
|
|
|
|
}
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if ( -f $statefile)
|
|
|
|
#{
|
|
|
|
# open (IN, '<', $statefile) or die "Unable to open state-file: $!\n";
|
|
|
|
# if (<IN> =~ /^sum:(\d+)/)
|
|
|
|
# {
|
|
|
|
# $sum = $1;
|
|
|
|
# }
|
|
|
|
# while (<IN>)
|
|
|
|
# {
|
|
|
|
# if (/^([0-9a-z.\-]+):(\d+)$/)
|
|
|
|
# {
|
|
|
|
# $status->{$1} = $2;
|
|
|
|
# }
|
|
|
|
# }
|
|
|
|
# close IN;
|
|
|
|
#}
|
|
|
|
|
|
|
|
if (! -d $configdir)
|
|
|
|
{
|
|
|
|
print "sum.value U\n";
|
|
|
|
foreach my $i (@status_list)
|
|
|
|
{
|
|
|
|
print "r$i.value U\n";
|
|
|
|
}
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
parseLogfile($configdir);
|
|
|
|
|
|
|
|
if ($ARGV[0] and $ARGV[0] eq "config")
|
|
|
|
{
|
|
|
|
# descriptions for the rrd file
|
|
|
|
my %descriptions = (
|
|
|
|
'crefused' => 'Connection refused',
|
|
|
|
'ctimeout' => 'Connection timed out',
|
2014-01-21 07:58:39 +01:00
|
|
|
'rtimeout' => 'Read connection timed out',
|
2013-12-25 04:30:51 +01:00
|
|
|
'refusedtalk' => 'Host refused connection',
|
|
|
|
'nohost' => 'Host not found',
|
|
|
|
'msrefused' => 'Mail service refused',
|
|
|
|
'noroute' => 'Route not found',
|
|
|
|
'usernotfound' => 'User not found',
|
|
|
|
'err450' => '450 mailbox not okay (REJECT)',
|
|
|
|
'err452' => '452 mailbox is full',
|
|
|
|
'err421' => '421 service not okay (REJECT)',
|
|
|
|
'err421a' => '421 service not okay (REJECT, SB)',
|
|
|
|
'err4' => 'General 4xx error',
|
|
|
|
'lostc' => 'Lost connection',
|
|
|
|
'active' => 'Active running',
|
|
|
|
'other' => 'Other error'
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
print "graph_title Postfix mailqueue log for $postfix\n";
|
|
|
|
print "graph_args --base 1000 -l 0\n"; # numbers not bytes
|
|
|
|
print "graph_vlabel Mails in Queue log\n";
|
|
|
|
print "graph_scale no\n"; # so we do not print "micro, milli, kilo, etc"
|
|
|
|
# print "graph_total Total\n";
|
2017-02-22 18:43:01 +01:00
|
|
|
print "graph_category mail\n";
|
2013-12-25 04:30:51 +01:00
|
|
|
foreach my $i (@status_list)
|
|
|
|
{
|
|
|
|
if ($descriptions{$i})
|
|
|
|
{
|
|
|
|
print "r$i.label ".$descriptions{$i}."\n";
|
|
|
|
print "r$i.type GAUGE\n";
|
|
|
|
print "r$i.draw ".(!$field ? 'AREA' : 'STACK')."\n";
|
|
|
|
print "r$i.min 0\n";
|
|
|
|
$field = 'AREA';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print "sum.label Sum\n";
|
|
|
|
print "sum.type GAUGE\n";
|
|
|
|
print "sum.draw LINE2\n";
|
|
|
|
print "sum.min 0\n";
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
print "sum.value $sum\n";
|
|
|
|
foreach my $i (@status_list)
|
|
|
|
{
|
|
|
|
print "r$i.value ".($status->{$i} ? $status->{$i} : 0)."\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
#if(-l $statefile) {
|
|
|
|
# die("$statefile is a symbolic link, refusing to touch it.");
|
|
|
|
#}
|
|
|
|
#open (OUT, '>', $statefile) or die "Unable to open statefile: $!\n";
|
|
|
|
#print OUT "sum:$sum\n";
|
|
|
|
#foreach my $i (@status_list)
|
|
|
|
#{
|
|
|
|
# print OUT "$i:".($status->{$i} ? $status->{$i} : 0)."\n";
|
|
|
|
#}
|
|
|
|
#close OUT;
|
|
|
|
|
|
|
|
sub parseLogfile
|
|
|
|
{
|
|
|
|
my ($fname) = @_;
|
|
|
|
|
|
|
|
# the search parts
|
|
|
|
%search = (
|
|
|
|
'crefused' => 'Connection refused',
|
|
|
|
'ctimeout' => 'Connection timed out',
|
|
|
|
'rtimeout' => 'read timeout',
|
|
|
|
'refusedtalk' => 'refused to talk to me: 554',
|
|
|
|
'nohost' => 'Host not found',
|
|
|
|
'msrefused' => 'server refused mail service"',
|
|
|
|
'noroute' => 'No route to host',
|
|
|
|
'usernotfound' => 'address rejected',
|
|
|
|
'err450' => ': 450 ',
|
|
|
|
'err452' => ': 452 ',
|
|
|
|
'err421' => ': 421 ',
|
|
|
|
'err421a' => ': 421)',
|
|
|
|
'err4' => 'said: 4',
|
|
|
|
'lostc' => 'lost connection with',
|
|
|
|
);
|
|
|
|
|
|
|
|
my $command = "mailq -C $fname";
|
|
|
|
|
|
|
|
open(FILE, "$command|") || die ("Cannot open $command: $!");
|
|
|
|
while (<FILE>)
|
|
|
|
{
|
|
|
|
if (/^\w{10,}\*\s/o)
|
|
|
|
{
|
|
|
|
$status->{'active'} ++;
|
|
|
|
}
|
|
|
|
elsif (/^\s*\(/o)
|
|
|
|
{
|
|
|
|
$set = 0;
|
|
|
|
foreach $i (@status_list)
|
|
|
|
{
|
|
|
|
if ($search{$i} && index($_, $search{$i}) >= 0 && !$set)
|
|
|
|
{
|
|
|
|
$status->{$i} ++;
|
|
|
|
$set = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$set)
|
|
|
|
{
|
|
|
|
$status->{'other'} ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(FILE) || die ("Cannot close $command: $!");
|
|
|
|
|
|
|
|
foreach $i (keys %{$status})
|
|
|
|
{
|
|
|
|
$sum += $status->{$i};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# vim:syntax=perl
|