mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
Merge pull request #419 from ldidry/new-plugin-postfwd2
Add new plugin : postfwd2
This commit is contained in:
commit
15ea8fce34
269
plugins/mail/postfwd2
Executable file
269
plugins/mail/postfwd2
Executable file
@ -0,0 +1,269 @@
|
||||
#!/usr/bin/perl
|
||||
# vim: set filetype=perl sw=4 tabstop=4 expandtab smartindent: #
|
||||
|
||||
=head1 NAME
|
||||
|
||||
postfwd2 - plugin to get stats from postfwd2
|
||||
|
||||
=head1 AUTHOR AND COPYRIGHT
|
||||
|
||||
Copyright 2013-2014 Luc Didry <luc AT didry.org>
|
||||
|
||||
=head1 HOWTO CONFIGURE AND USE :
|
||||
|
||||
=over
|
||||
|
||||
=item - /etc/munin/plugin-conf.d/postfwd2
|
||||
|
||||
[postfwd2]
|
||||
user root
|
||||
env.path /usr/local/sbin/postfwd2 # OPTIONAL : looks for postfwd2 in /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
|
||||
env.include .*ISBAD #OPTIONAL
|
||||
env.exclude .*ISGOOD #OPTIONAL
|
||||
|
||||
=item - env.include and env.exclude
|
||||
|
||||
This are perl regexp.
|
||||
If env.include is set and env.exclude is not, only the policy which name
|
||||
matchs will be used.
|
||||
If env.exclude is set and env.include is not, only the policy which name NOT
|
||||
matchs will be used.
|
||||
If both are set, a policy which name matchs the both regex will be used, a
|
||||
policy which matchs only the exclude regexp will NOT be used and a policy
|
||||
which match not the exclude regex will be used, even if it not matchs the
|
||||
include regexp.
|
||||
if none are set, all the policy will be used.
|
||||
|
||||
|
||||
=item - /etc/munin/plugins
|
||||
|
||||
cp postfwd2 /etc/munin/plugins
|
||||
|
||||
|
||||
=item - restart Munin node
|
||||
|
||||
service munin-node restart
|
||||
|
||||
=back
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
=cut
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use Munin::Plugin;
|
||||
|
||||
need_multigraph();
|
||||
|
||||
my @keys =qw/cache_queries cache_stats policy_requests policy_timeout policy_matchs/;
|
||||
my %graphs = (
|
||||
cache_queries => {
|
||||
title => 'Cache queries',
|
||||
vlabel => 'Nb of cache queries',
|
||||
series => {
|
||||
cache_queries => {
|
||||
label => 'Cache queries',
|
||||
type => 'COUNTER'
|
||||
}
|
||||
},
|
||||
},
|
||||
cache_stats => {
|
||||
title => 'Cache stats',
|
||||
vlabel => 'percent',
|
||||
series => {
|
||||
cache_requests => {
|
||||
label => 'Requests hitrate',
|
||||
type => 'GAUGE'
|
||||
},
|
||||
cache_dns => {
|
||||
label => 'Dns hitrate',
|
||||
type => 'GAUGE'
|
||||
},
|
||||
cache_rates => {
|
||||
label => 'Rates hitrate',
|
||||
type => 'GAUGE'
|
||||
}
|
||||
},
|
||||
},
|
||||
policy_requests => {
|
||||
title => 'Policy requests',
|
||||
vlabel => 'Nb of policy requests',
|
||||
series => {
|
||||
policy_requests => {
|
||||
label => 'Policy requests',
|
||||
type => 'COUNTER'
|
||||
}
|
||||
},
|
||||
},
|
||||
policy_timeout => {
|
||||
title => 'Policy timeout',
|
||||
vlabel => 'Nb of policy timeout',
|
||||
series => {
|
||||
policy_timeout => {
|
||||
label => 'Policy timeout',
|
||||
type => 'COUNTER'
|
||||
}
|
||||
}
|
||||
},
|
||||
policy_matchs => {
|
||||
title => 'Policy matchs',
|
||||
vlabel => 'Matchs percentage'
|
||||
}
|
||||
);
|
||||
|
||||
my $PLUGIN_NAME = 'postfwd2';
|
||||
my $CACHEFILE="$Munin::Plugin::pluginstatedir/postfwd2.cache";
|
||||
|
||||
my ($include, $exclude) = ($ENV{include}, $ENV{exclude});
|
||||
if (defined($include) && (!defined($exclude))) {
|
||||
$exclude = '.*';
|
||||
}
|
||||
|
||||
##### Cache file, to continue to graph old policies which doesn't exist anymore
|
||||
if (!(-f $CACHEFILE) || !(-e $CACHEFILE)) {
|
||||
open (FILE, ">", $CACHEFILE) or munin_exit_fail();
|
||||
close(FILE);
|
||||
}
|
||||
open (FILE, "<", $CACHEFILE) or munin_exit_fail();
|
||||
my @policies = <FILE>;
|
||||
close(FILE);
|
||||
my %policies = map { $_, 1 } @policies;
|
||||
foreach my $policy (keys %policies) {
|
||||
chomp $policy;
|
||||
$graphs{policy_matchs}->{series}->{$policy}->{type} = 'GAUGE';
|
||||
$graphs{policy_matchs}->{series}->{$policy}->{label} = $policy;
|
||||
$graphs{policy_matchs}->{series}->{$policy}->{value} = 0;
|
||||
}
|
||||
|
||||
##### Check postfwd2 path
|
||||
if (!defined($ENV{path}) || !(-x $ENV{path})) {
|
||||
foreach my $path (qw{/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin}) {
|
||||
$ENV{path} = $path.'/postfwd2' if (!defined($ENV{path}) && -x $path.'/postfwd2');
|
||||
last if (defined($ENV{path}));
|
||||
}
|
||||
}
|
||||
munin_exit_fail() unless (defined($ENV{path}) && -x $ENV{path});
|
||||
|
||||
##### I have to parse the output BEFORE config, since policy matchs are dependant of the postfwd --dumpstats output
|
||||
open(DATA, $ENV{path}.' --dumpstats |') or munin_exit_fail();
|
||||
my $total_requests;
|
||||
while(defined (my $data = <DATA>)) {
|
||||
if ($data =~ m/^\[STATS\] postfwd2::cache .*: (\d+) queries since/) {
|
||||
$graphs{cache_queries}->{series}->{cache_queries}->{value} = $1;
|
||||
}
|
||||
if ($data =~ m/^\[STATS\] Hitrates: ([\.\d]+)% requests, ([\.\d]+)% dns, ([\.\d]+)% rates$/) {
|
||||
$graphs{cache_stats}->{series}->{cache_requests}->{value} = $1;
|
||||
$graphs{cache_stats}->{series}->{cache_dns}->{value} = $2;
|
||||
$graphs{cache_stats}->{series}->{cache_rates}->{value} = $3;
|
||||
}
|
||||
if ($data =~ m/^\[STATS\] postfwd2::policy .*: (\d+) requests since/) {
|
||||
$graphs{policy_requests}->{series}->{policy_requests}->{value} = $1;
|
||||
$total_requests = $1;
|
||||
}
|
||||
if ($data =~ m/^\[STATS\] Timeouts: .*% \((\d+) of \d+ dns queries\)$/) {
|
||||
$graphs{policy_timeout}->{series}->{policy_timeout}->{value} = $1;
|
||||
}
|
||||
if ($data =~ m/^\[STATS\] +(\d+) matches for id: (.*)$/) {
|
||||
my ($value, $label) = ($1, $2);
|
||||
if ( ( !defined($exclude) ) || ( $label !~ m/$exclude/ || ( defined($include) && $label =~ m/$include/ ) ) ) {
|
||||
if (!defined($policies{$label})) {
|
||||
open (FILE, ">>", $CACHEFILE) or munin_exit_fail();
|
||||
print FILE $label, "\n";
|
||||
close(FILE);
|
||||
$graphs{policy_matchs}->{series}->{$label}->{type} = 'GAUGE';
|
||||
$graphs{policy_matchs}->{series}->{$label}->{label} = $label;
|
||||
}
|
||||
$graphs{policy_matchs}->{series}->{$label}->{value} = sprintf("%.2f", 100*$value/$total_requests);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(DATA);
|
||||
|
||||
##### config
|
||||
if( (defined $ARGV[0]) && ($ARGV[0] eq 'config') ) {
|
||||
foreach my $key (@keys) {
|
||||
print 'multigraph postfwd2_', $key, "\n";
|
||||
print 'graph_title Postfwd2 ', $graphs{$key}->{title}, "\n";
|
||||
print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
|
||||
my $args = ($key eq 'cache_stats') ? ' --upper-limit 100 --rigid' : '';
|
||||
print 'graph_args --lower-limit 0', $args, "\n";
|
||||
print 'graph_category mail', "\n";
|
||||
if ($key eq 'policy_matchs') {
|
||||
print 'graph_width 600', "\n";
|
||||
my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
|
||||
foreach my $label (@pol_keys) {
|
||||
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||
print $label, '.draw LINE', "\n";
|
||||
print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
|
||||
}
|
||||
foreach my $label (@pol_keys) {
|
||||
print 'multigraph postfwd2_', $key, '.', $label, "\n";
|
||||
print 'graph_title Postfwd2 ', $label, "\n";
|
||||
print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
|
||||
print 'graph_width 600', "\n";
|
||||
print 'graph_args --lower-limit 0 ', $args, "\n";
|
||||
print 'graph_category others', "\n";
|
||||
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||
print $label, '.draw LINE', "\n";
|
||||
print $label, '.type GAUGE', "\n";
|
||||
}
|
||||
} else {
|
||||
foreach my $label (keys %{$graphs{$key}->{series}}) {
|
||||
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||
print $label, '.draw AREASTACK', "\n";
|
||||
print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
munin_exit_done();
|
||||
}
|
||||
|
||||
##### fetch
|
||||
foreach my $key (@keys) {
|
||||
print 'multigraph postfwd2_', $key, "\n";
|
||||
if ($key eq 'policy_matchs') {
|
||||
my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
|
||||
foreach my $label (@pol_keys) {
|
||||
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||
}
|
||||
foreach my $label (@pol_keys) {
|
||||
print 'multigraph postfwd2_', $key, '.', $label, "\n";
|
||||
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||
}
|
||||
} else {
|
||||
foreach my $label (keys %{$graphs{$key}->{series}}) {
|
||||
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
munin_exit_done();
|
||||
|
||||
#
|
||||
##
|
||||
### INTERNALS FONCTIONS
|
||||
###############################################################################
|
||||
sub munin_exit_done {
|
||||
munin_exit(0);
|
||||
} ## sub munin_exit_done
|
||||
|
||||
sub munin_exit_fail {
|
||||
munin_exit(1);
|
||||
} ## sub munin_exit_fail
|
||||
|
||||
sub munin_exit {
|
||||
my $exitcode = shift;
|
||||
exit($exitcode) if(defined $exitcode);
|
||||
exit(1);
|
||||
} ## sub munin_exit
|
Loading…
Reference in New Issue
Block a user