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';
49 our $Interval = defined ($ENV{'COLLECTD_INTERVAL'}) ? (0 + $ENV{'COLLECTD_INTERVAL'}) : 300;
50 our $Hostname = defined ($ENV{'COLLECTD_HOSTNAME'}) ? $ENV{'COLLECTD_HOSTNAME'} : '';
59 This script reads it's configuration from F</etc/exec-munin.conf>. The
60 configuration is read using C<Config::General> which understands a Apache-like
61 config syntax, so it's very similar to the F<collectd.conf> syntax, too.
63 Here's a short sample config:
66 AddType voltage-out out
68 Script /usr/lib/munin/plugins/nut
70 The options have the following semantic (i.E<nbsp>e. meaning):
74 =item B<AddType> I<to> I<from> [I<from> ...]
76 collectd uses B<types> to specify how data is structured. In Munin all data is
77 structured the same way, so some way of telling collectd how to handle the data
78 is needed. This option translates the so called "field names" of Munin to the
79 "types" of collectd. If more than one field are of the same type, e.E<nbsp>g.
80 the C<nut> plugin above provides C<in> and C<out> which are both voltages, you
81 can use a hyphen to add a "type instance" to the type.
83 For a list of already defined "types" look at the F<types.db> file in
84 collectd's shared data directory, e.E<nbsp>g. F</usr/share/collectd/>.
86 =item B<Interval> I<Seconds>
88 Sets the interval in which the plugins are executed. This doesn't need to match
89 the interval setting of the collectd daemon. Usually, you want to execute the
90 Munin plugins much less often, e.E<nbsp>g. every 300 seconds versus every 10
93 =item B<Script> I<File>
95 Adds a script to the list of scripts to be executed once per I<Interval>
102 sub handle_config_addtype
106 for (my $i = 0; $i < @$list; $i++)
108 my ($to, @from) = split (' ', $list->[$i]);
109 for (my $j = 0; $j < @from; $j++)
111 $TypeMap->{$from[$j]} = $to;
114 } # handle_config_addtype
116 sub handle_config_script
120 for (my $i = 0; $i < @$scripts; $i++)
122 my $script = $scripts->[$i];
125 print STDERR "Script `$script' doesn't exist.\n";
129 print STDERR "Script `$script' exists but is not executable.\n";
133 push (@$Scripts, $script);
136 } # handle_config_script
142 if (defined ($config->{'addtype'}))
144 if (ref ($config->{'addtype'}) eq 'ARRAY')
146 handle_config_addtype ($config->{'addtype'});
148 elsif (ref ($config->{'addtype'}) eq '')
150 handle_config_addtype ([$config->{'addtype'}]);
154 print STDERR "Cannot handle ref type '"
155 . ref ($config->{'addtype'}) . "' for option 'AddType'.\n";
159 if (defined ($config->{'script'}))
161 if (ref ($config->{'script'}) eq 'ARRAY')
163 handle_config_script ($config->{'script'});
165 elsif (ref ($config->{'script'}) eq '')
167 handle_config_script ([$config->{'script'}]);
171 print STDERR "Cannot handle ref type '"
172 . ref ($config->{'script'}) . "' for option 'Script'.\n";
176 if (defined ($config->{'interval'})
177 && (ref ($config->{'interval'}) eq ''))
179 my $num = int ($config->{'interval'});
185 } # handle_config }}}
193 my $host = $Hostname || hostname () || 'localhost';
194 if (!open ($fh, '-|', $script))
196 print STDERR "Cannot execute $script: $!";
200 $pinst = basename ($script);
202 while (my $line = <$fh>)
205 if ($line =~ m#^([^\.\-/]+)\.value\s+($RE{num}{real})#)
209 my $type = (defined ($TypeMap->{$field})) ? $TypeMap->{$field} : $field;
210 my $ident = "$host/munin-$pinst/$type";
214 print qq(PUTVAL "$ident" interval=$Interval $time:$value\n);
226 my %config = ParseConfig (-ConfigFile => $ConfigFile,
228 -LowerCaseNames => 1);
229 handle_config (\%config);
234 $next_run = $last_run + $Interval;
241 while ((my $timeleft = ($next_run - time ())) > 0)
250 This script requires the following Perl modules to be installed:
254 =item C<Config::General>
256 =item C<Regexp::Common>
262 L<http://munin.projects.linpro.no/>,
263 L<http://collectd.org/>,
268 Florian octo Forster E<lt>octo at verplant.orgE<gt>
272 # vim: set sw=2 sts=2 ts=8 fdm=marker :