Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / munin / munin_stats_plugins @ d7f54f3e

Historique | Voir | Annoter | Télécharger (3,92 ko)

1 accb5b10 ?var Arnfj?r? Bjarmason
#!/usr/bin/env perl
2
use 5.010;
3
use strict;
4
use warnings;
5
use autodie;
6
use Munin::Plugin;
7
use File::Temp qw(tempdir tempfile);
8
use Time::HiRes qw(gettimeofday tv_interval);
9
use File::Spec::Functions qw(catfile);
10
use File::Basename qw(basename);
11
12
=head1 NAME
13
14
munin_stats_plugins - Report the time it takes to run all munin plugins
15
16
=head1 SYNOPSIS
17
18
In F</etc/munin/plugin-conf.d/munin-node>, because we invoke plugins
19
with munin-run, some of which may need root privileges:
20
21
    [munin_stats_plugins]
22
    user root
23
24
Put this in cron somewhere:
25
26
    # Refresh the statistics
27
    MUNIN_STATS_PLUGINS_RELOAD=1 munin-run munin_stats_plugins
28
29
E.g.:
30
31
    40 4  * * * root MUNIN_STATS_PLUGINS_RELOAD=1 munin-run munin_stats_plugins
32
33
Then run it:
34
35
    # Get the statistics
36
    munin-run munin_stats_plugins
37
38
=head1 DESCRIPTION
39
40
Runs all the munin plugins in F</etc/munin/plugins> and reports the
41
time it takes to run each one with C<system> and L<Time::HiRes>. Since
42
running all the plugins again on each munin-update run would lead to
43
epic recursive failure, you have to reload the statistics database
44
yourself by reloading it in cron somewhere.
45
46
=head1 AUTHOR
47
48 d7f54f3e Lars Kruse
Ævar Arnfjörð Bjarmason <avar@cpan.org>
49 accb5b10 ?var Arnfj?r? Bjarmason
50
=head1 LICENSE
51
52
This program is in the public domain.
53
54
=head1 MAGIC MARKERS
55
56
 #%# family=manual
57
58
=cut
59
60
my $statedir  = $ENV{MUNIN_PLUGSTATE};
61
my $statefile = $0; $statefile =~ s[^.*/][];
62
my $cache = catfile($statedir, $statefile . '-cache');
63
my $cache_tmp = "$cache.tmp";
64
65
my @plugins = parse_plugin_time($cache);
66
67
# We should reload our data
68
if (not $ARGV[0] and $ENV{MUNIN_STATS_PLUGINS_RELOAD}) {
69
    $ARGV[0] = 'reload';
70
}
71
72
given ($ARGV[0]) {
73
    when ("reload") {
74
        # Plugin names
75
        my @plugs = plugin_names();
76
77
        # Run all the plugins
78
        my $time = plugin_times(@plugs);
79
80
        write_plugin_times($cache_tmp, $cache, $time);
81
    }
82
    when ("config") {
83
        print <<END;
84
graph_title Munin plugin processing time
85
graph_scale yes
86
graph_vlabel seconds
87
graph_category munin
88
graph_info Shows the processing time of munin plugins in seconds
89
END
90
        for my $plugin (@plugins) {
91
            my ($time, $name) = @$plugin;
92
            my $fieldname = clean_fieldname($name);
93
            print <<END;
94
$fieldname.label $name
95
$fieldname.info The processing time of $name
96
$fieldname.draw AREASTACK
97
END
98
        }
99
    }
100
    default {
101
        for my $plugin (@plugins) {
102
            my ($time, $name) = @$plugin;
103
            my $fieldname = clean_fieldname($name);
104
            print <<END;
105
$fieldname.value $time
106
END
107
        }
108
    }
109
}
110
111
sub slurp {
112
    do {
113
        local (@ARGV, $/) = shift;
114
        scalar <>;
115
    };
116
}
117
118
sub parse_plugin_time
119
{
120
    my ($file) = @_;
121
122
    my $cont = slurp($file);
123
124
    my @plugins;
125
    while ($cont =~ /^ (?<time>[\d.]+) \s+ (?<plugin>.*) $/mgx) {
126
        push @plugins => [ $+{time} => $+{plugin} ];
127
    }
128
129
    # Sort by size
130
    @plugins = sort { $b->[0] <=> $a->[0] } @plugins;
131
132
    @plugins;
133
}
134
135
sub plugin_names {
136
    map { basename $_ } grep { -x } glob "/etc/munin/plugins/*";
137
}
138
139
sub plugin_times {
140
    my (@p) = @_;
141
    my %time;
142
143
    my $dir = tempdir("munin-stats-plugins-XXXX", CLEANUP => 1, TMPDIR => 1);
144
145
    for my $plugin (@p) {
146
        my ($fh, $file) = tempfile(DIR => $dir);
147
        my $t0 = [gettimeofday];
148
        if (system qq[MUNIN_STATS_PLUGINS_RELOAD=0 munin-run "$plugin" >"$file" 2>&1]) {
149
            my $cont = slurp($file);
150
            die "munin-run: Failed to run plugin $plugin: $?, output: $cont";
151
        }
152
        my $t1 = [gettimeofday];
153
154
        my $elapsed = tv_interval($t0, $t1);
155
        $time{$plugin} = sprintf "%0.2f", $elapsed;
156
    }
157
158
    return \%time;
159
}
160
161
sub write_plugin_times {
162
    my ($tmp, $real, $time) = @_;
163
164
    # Write out the runtimes to a tempfile
165
    open my $fh, ">", $cache_tmp;
166
    while (my ($p, $t) = each %$time) {
167
        say $fh "$t $p";
168
    }
169
    close $fh;
170
171
    # Rename the temp to the real thing. If we wrote it to begin
172
    # with we might have a race condition.
173
    rename $cache_tmp, $cache;
174
}