4 # collectd - contrib/exec-munin.px
5 # Copyright (C) 2007,2008 Florian Forster
7 # This program is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by the
9 # Free Software Foundation; only version 2 of the License is applicable.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 # Florian octo Forster <octo at verplant.org>
33 This script allows you to use plugins that were written for Munin with
34 collectd's C<exec-plugin>. Since the data models of Munin and collectd are
35 quite different rewriting the plugins should be preferred over using this
36 transition layer. Having more than one "data source" for one "data set" doesn't
37 work with this script, for example.
41 use Sys::Hostname ('hostname');
42 use File::Basename ('basename');
43 use Config::General ('ParseConfig');
44 use Regexp::Common ('number');
46 our $ConfigFile = '/etc/exec-munin.conf';
58 This script reads it's configuration from F</etc/exec-munin.conf>. The
59 configuration is read using C<Config::General> which understands a Apache-like
60 config syntax, so it's very similar to the F<collectd.conf> syntax, too.
62 Here's a short sample config:
65 AddType voltage-out out
67 Script /usr/lib/munin/plugins/nut
69 The options have the following semantic (i.E<nbsp>e. meaning):
73 =item B<AddType> I<to> I<from> [I<from> ...]
75 collectd uses B<types> to specify how data is structured. In Munin all data is
76 structured the same way, so some way of telling collectd how to handle the data
77 is needed. This option translates the so called "field names" of Munin to the
78 "types" of collectd. If more than one field are of the same type, e.E<nbsp>g.
79 the C<nut> plugin above provides C<in> and C<out> which are both voltages, you
80 can use a hyphen to add a "type instance" to the type.
82 For a list of already defined "types" look at the F<types.db> file in
83 collectd's shared data directory, e.E<nbsp>g. F</usr/share/collectd/>.
85 =item B<Interval> I<Seconds>
87 Sets the interval in which the plugins are executed. This doesn't need to match
88 the interval setting of the collectd daemon. Usually, you want to execute the
89 Munin plugins much less often, e.E<nbsp>g. every 300 seconds versus every 10
92 =item B<Script> I<File>
94 Adds a script to the list of scripts to be executed once per I<Interval>
101 sub handle_config_addtype
105 for (my $i = 0; $i < @$list; $i++)
107 my ($to, @from) = split (' ', $list->[$i]);
108 for (my $j = 0; $j < @from; $j++)
110 $TypeMap->{$from[$j]} = $to;
113 } # handle_config_addtype
115 sub handle_config_script
119 for (my $i = 0; $i < @$scripts; $i++)
121 my $script = $scripts->[$i];
124 print STDERR "Script `$script' doesn't exist.\n";
128 print STDERR "Script `$script' exists but is not executable.\n";
132 push (@$Scripts, $script);
135 } # handle_config_script
141 if (defined ($config->{'addtype'}))
143 if (ref ($config->{'addtype'}) eq 'ARRAY')
145 handle_config_addtype ($config->{'addtype'});
147 elsif (ref ($config->{'addtype'}) eq '')
149 handle_config_addtype ([$config->{'addtype'}]);
153 print STDERR "Cannot handle ref type '"
154 . ref ($config->{'addtype'}) . "' for option 'AddType'.\n";
158 if (defined ($config->{'script'}))
160 if (ref ($config->{'script'}) eq 'ARRAY')
162 handle_config_script ($config->{'script'});
164 elsif (ref ($config->{'script'}) eq '')
166 handle_config_script ([$config->{'script'}]);
170 print STDERR "Cannot handle ref type '"
171 . ref ($config->{'script'}) . "' for option 'Script'.\n";
175 if (defined ($config->{'interval'})
176 && (ref ($config->{'interval'}) eq ''))
178 my $num = int ($config->{'interval'});
184 } # handle_config }}}
192 my $host = hostname () || 'localhost';
193 if (!open ($fh, '-|', $script))
195 print STDERR "Cannot execute $script: $!";
199 $pinst = basename ($script);
201 while (my $line = <$fh>)
204 if ($line =~ m#^([^\.\-/]+)\.value\s+($RE{num}{real})#)
208 my $type = (defined ($TypeMap->{$field})) ? $TypeMap->{$field} : $field;
210 print "$host/munin-$pinst/$type interval=$Interval $time:$value\n";
222 my %config = ParseConfig (-ConfigFile => $ConfigFile,
224 -LowerCaseNames => 1);
225 handle_config (\%config);
230 $next_run = $last_run + $Interval;
237 while ((my $timeleft = ($next_run - time ())) > 0)
246 This script requires the following Perl modules to be installed:
250 =item C<Config::General>
252 =item C<Regexp::Common>
258 L<http://munin.projects.linpro.no/>,
259 L<http://collectd.org/>,
264 Florian octo Forster E<lt>octo at verplant.orgE<gt>
268 # vim: set sw=2 sts=2 ts=8 fdm=marker :