Projet

Général

Profil

Révision 29e732d7

ID29e732d7ee389a3a96c4181fb46565a2b9ae795c
Parent 08241c12
Enfant e838e28e

Ajouté par Luc Didry il y a presque 12 ans

Add new plugin : postfwd2

Voir les différences:

plugins/mail/postfwd2
1
#!/usr/bin/perl
2
# vim: set filetype=perl sw=4 tabstop=4 expandtab smartindent: #
3

  
4
=head1 NAME
5

  
6
  postfwd2 - plugin to get stats from postfwd2
7

  
8
=head1 AUTHOR AND COPYRIGHT
9

  
10
  Copyright 2013 Luc Didry <luc AT didry.org>
11

  
12
=head1 HOWTO CONFIGURE AND USE :
13

  
14
=over
15

  
16
=item - /etc/munin/plugin-conf.d/postfwd2
17

  
18
     [postfwd2]
19
     user root
20
     env.path /usr/local/sbin/postfwd2 # OPTIONAL : looks for postfwd2 in /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
21
     env.include .*ISBAD #OPTIONAL
22
     env.exclude .*ISGOOD #OPTIONAL
23

  
24
=item - env.include and env.exclude
25

  
26
  This are perl regexp.
27
  If env.include is set and env.exclude is not, only the policy which name
28
  matchs will be used.
29
  If env.exclude is set and env.include is not, only the policy which name NOT
30
  matchs will be used.
31
  If both are set, a policy which name matchs the both regex will be used, a
32
  policy which matchs only the exclude regexp will NOT be used and a policy
33
  which match not the exclude regex will be used, even if it not matchs the
34
  include regexp.
35
  if none are set, all the policy will be used.
36

  
37

  
38
=item - /etc/munin/plugins
39

  
40
     cp postfwd2 /etc/munin/plugins
41

  
42

  
43
=item - restart Munin node
44

  
45
     service munin-node restart
46

  
47
=back
48

  
49
=head1 LICENSE
50

  
51
  This program is free software: you can redistribute it and/or modify it under
52
  the terms of the GNU General Public License as published by the Free Software
53
  Foundation, either version 3 of the License, or any later version.
54

  
55
  This program is distributed in the hope that it will be useful, but WITHOUT
56
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
57
  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
58

  
59
  You should have received a copy of the GNU General Public License along with
60
  this program.  If not, see <http://www.gnu.org/licenses/>.
61

  
62
=cut
63

  
64
use warnings;
65
use strict;
66
use Munin::Plugin;
67

  
68
need_multigraph();
69

  
70
my @keys =qw/cache_queries cache_stats policy_requests policy_timeout policy_matchs/;
71
my %graphs = (
72
    cache_queries => {
73
        title  => 'Cache queries',
74
        vlabel => 'Nb of cache queries',
75
        series => {
76
            cache_queries => {
77
                label => 'Cache queries',
78
                type  => 'COUNTER'
79
            }
80
        },
81
    },
82
    cache_stats => {
83
        title  => 'Cache stats',
84
        vlabel => 'percent',
85
        series => {
86
            cache_requests => {
87
                label => 'Requests hitrate',
88
                type  => 'GAUGE'
89
            },
90
            cache_dns => {
91
                label => 'Dns hitrate',
92
                type  => 'GAUGE'
93
            },
94
            cache_rates => {
95
                label => 'Rates hitrate',
96
                type  => 'GAUGE'
97
            }
98
        },
99
    },
100
    policy_requests => {
101
        title  => 'Policy requests',
102
        vlabel => 'Nb of policy requests',
103
        series => {
104
            policy_requests => {
105
                label => 'Policy requests',
106
                type  => 'COUNTER'
107
            }
108
        },
109
    },
110
    policy_timeout => {
111
        title  => 'Policy timeout',
112
        vlabel => 'Nb of policy timeout',
113
        series => {
114
            policy_timeout => {
115
                label => 'Policy timeout',
116
                type  => 'COUNTER'
117
            }
118
        }
119
    },
120
    policy_matchs => {
121
        title  => 'Policy matchs',
122
        vlabel => 'Matchs percentage'
123
    }
124
);
125

  
126
my $PLUGIN_NAME = 'postfwd2';
127
my $CACHEFILE="$Munin::Plugin::pluginstatedir/postfwd2.cache";
128

  
129
my ($include, $exclude) = ($ENV{include}, $ENV{exclude});
130
if (defined($include) && (!defined($exclude))) {
131
    $exclude = '.*';
132
}
133

  
134
##### Cache file, to continue to graph old policies which doesn't exist anymore
135
if (!(-f $CACHEFILE) || !(-e $CACHEFILE)) {
136
    open (FILE, ">", $CACHEFILE) or munin_exit_fail();
137
    close(FILE);
138
}
139
open (FILE, "<", $CACHEFILE) or munin_exit_fail();
140
my @policies = <FILE>;
141
close(FILE);
142
my %policies = map { $_, 1 } @policies;
143
foreach my $policy (keys %policies) {
144
    chomp $policy;
145
    $graphs{policy_matchs}->{series}->{$policy}->{type}   = 'GAUGE';
146
    $graphs{policy_matchs}->{series}->{$policy}->{label}  = $policy;
147
    $graphs{policy_matchs}->{series}->{$policy}->{value}  = 0;
148
}
149

  
150
##### Check postfwd2 path
151
if (!defined($ENV{path}) || !(-x $ENV{path})) {
152
    foreach my $path (qw{/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin}) {
153
        $ENV{path} = $path.'/postfwd2' if (!defined($ENV{path}) && -x $path.'/postfwd2');
154
        last if (defined($ENV{path}));
155
    }
156
}
157
munin_exit_fail() unless (defined($ENV{path}) && -x $ENV{path});
158

  
159
##### I have to parse the output BEFORE config, since policy matchs are dependant of the postfwd --dumpstats output
160
open(DATA, $ENV{path}.' --dumpstats |') or munin_exit_fail();
161
my $total_requests;
162
while(defined (my $data = <DATA>)) {
163
    if ($data =~ m/^\[STATS\] postfwd2::cache .*: (\d+) queries since/) {
164
         $graphs{cache_queries}->{series}->{cache_queries}->{value} = $1;
165
    }
166
    if ($data =~ m/^\[STATS\] Hitrates: ([\.\d]+)% requests, ([\.\d]+)% dns, ([\.\d]+)% rates$/) {
167
        $graphs{cache_stats}->{series}->{cache_requests}->{value} = $1;
168
        $graphs{cache_stats}->{series}->{cache_dns}->{value} = $2;
169
        $graphs{cache_stats}->{series}->{cache_rates}->{value} = $3;
170
    }
171
    if ($data =~ m/^\[STATS\] postfwd2::policy .*: (\d+) requests since/) {
172
        $graphs{policy_requests}->{series}->{policy_requests}->{value} = $1;
173
        $total_requests = $1;
174
    }
175
    if ($data =~ m/^\[STATS\] Timeouts: .*% \((\d+) of \d+ dns queries\)$/) {
176
        $graphs{policy_timeout}->{series}->{policy_timeout}->{value} = $1;
177
    }
178
    if ($data =~ m/^\[STATS\] +(\d+) matches for id:  (.*)$/) {
179
        my ($value, $label) = ($1, $2);
180
        if ( ( !defined($exclude) ) || ( $label !~ m/$exclude/ || ( defined($include) && $label =~ m/$include/ ) ) ) {
181
            if (!defined($policies{$label})) {
182
                open (FILE, ">>", $CACHEFILE) or munin_exit_fail();
183
                print FILE $label, "\n";
184
                close(FILE);
185
                $graphs{policy_matchs}->{series}->{$label}->{type} = 'GAUGE';
186
                $graphs{policy_matchs}->{series}->{$label}->{label} = $label;
187
            }
188
            $graphs{policy_matchs}->{series}->{$label}->{value} = sprintf("%.2f", 100*$value/$total_requests);
189
        }
190
    }
191
}
192
close(DATA);
193

  
194
##### config
195
if( (defined $ARGV[0]) && ($ARGV[0] eq 'config') ) {
196
    foreach my $key (@keys) {
197
        print 'multigraph postfwd2_', $key, "\n";
198
        print 'graph_title Postfwd2 ', $graphs{$key}->{title}, "\n";
199
        print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
200
        my $args = ($key eq 'cache_stats') ? ' --upper-limit 100 --rigid' : '';
201
        print 'graph_args --lower-limit 0', $args, "\n";
202
        print 'graph_category mail', "\n";
203
        if ($key eq 'policy_matchs') {
204
            print 'graph_width 600', "\n";
205
            my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
206
            foreach my $label (@pol_keys) {
207
                print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
208
                print $label, '.draw LINE', "\n";
209
                print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
210
            }
211
            foreach my $label (@pol_keys) {
212
                print 'multigraph postfwd2_', $key, '.', $label, "\n";
213
                print 'graph_title Postfwd2 ', $label, "\n";
214
                print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
215
                print 'graph_width 600', "\n";
216
                print 'graph_args --lower-limit 0 ', $args, "\n";
217
                print 'graph_category others', "\n";
218
                print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
219
                print $label, '.draw LINE', "\n";
220
                print $label, '.type GAUGE', "\n";
221
            }
222
        } else {
223
            foreach my $label (keys %{$graphs{$key}->{series}}) {
224
                print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
225
                print $label, '.draw AREASTACK', "\n";
226
                print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
227
            }
228
        }
229
    }
230
    munin_exit_done();
231
}
232

  
233
##### fetch
234
foreach my $key (@keys) {
235
    print 'multigraph postfwd2_', $key, "\n";
236
    if ($key eq 'policy_matchs') {
237
        my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
238
        foreach my $label (@pol_keys) {
239
            print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
240
        }
241
        foreach my $label (@pol_keys) {
242
            print 'multigraph postfwd2_', $key, '.', $label, "\n";
243
            print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
244
        }
245
    } else {
246
        foreach my $label (keys %{$graphs{$key}->{series}}) {
247
            print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
248
        }
249
    }
250
}
251
munin_exit_done();
252

  
253
#
254
##
255
### INTERNALS FONCTIONS
256
###############################################################################
257
sub munin_exit_done {
258
    munin_exit(0);
259
} ## sub munin_exit_done
260

  
261
sub munin_exit_fail {
262
    munin_exit(1);
263
} ## sub munin_exit_fail
264

  
265
sub munin_exit {
266
    my $exitcode = shift;
267
    exit($exitcode) if(defined $exitcode);
268
    exit(1);
269
} ## sub munin_exit

Formats disponibles : Unified diff