summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 96a9cd4)
raw | patch | inline | side by side (parent: 96a9cd4)
author | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Sat, 3 Nov 2007 15:28:35 +0000 (16:28 +0100) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Sat, 3 Nov 2007 15:28:35 +0000 (16:28 +0100) |
The script has an embedded POD documentation.
contrib/README | patch | blob | history | |
contrib/exec-munin.conf | [new file with mode: 0644] | patch | blob |
contrib/exec-munin.px | [new file with mode: 0755] | patch | blob |
diff --git a/contrib/README b/contrib/README
index 685903b3f171ffc5a66880fbc24c766cca2c2128..6f0836f82387d90613aa0b8f98a84746e5b433fe 100644 (file)
--- a/contrib/README
+++ b/contrib/README
datadir: "/var/lib/collectd/rrd/"
libdir: "/usr/lib/collectd/"
+exec-munin.px
+-------------
+ Script to be used with the exec-plugin (see collectd-exec(5) for details)
+which executes munin plugins, parses the output and translates it to a format
+the exec-plugin understands. The features are limited - changing the munin
+plugins to use the output format understood by the exec-plugin is recommended.
+See the embedded POD documentation for more details:
+ $ perldoc contrib/exec-munin.px
+
extractDS.px
------------
Creates a new RRD-file with only one data-source (DS) of the source-RRD-
diff --git a/contrib/exec-munin.conf b/contrib/exec-munin.conf
--- /dev/null
+++ b/contrib/exec-munin.conf
@@ -0,0 +1,6 @@
+AddType temperature temperature
+
+Interval 300
+
+Script /tmp/ipmisens2
+Script /tmp/munin-sensors.pl
diff --git a/contrib/exec-munin.px b/contrib/exec-munin.px
--- /dev/null
+++ b/contrib/exec-munin.px
@@ -0,0 +1,248 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+=head1 NAME
+
+exec-munin.px
+
+=head1 DESCRIPTION
+
+This script allows you to use plugins that were written for Munin with
+collectd's C<exec-plugin>. Since the data models of Munin and collectd are
+quite different rewriting the plugins should be preferred over using this
+transition layer. Having more than one "data source" for one "data set" doesn't
+work with this script, for example.
+
+=cut
+
+use Sys::Hostname ('hostname');
+use File::Basename ('basename');
+use Config::General ('ParseConfig');
+use Regexp::Common ('number');
+
+our $ConfigFile = '/etc/exec-munin.conf';
+our $TypeMap = {};
+our $Scripts = [];
+our $Interval = 300;
+
+main ();
+exit (0);
+
+# Configuration
+# {{{
+
+=head1 CONFIGURATION
+
+This script reads it's configuration from F</etc/exec-munin.conf>. The
+configuration is read using C<Config::General> which understands a Apache-like
+config syntax, so it's very similar to the F<collectd.conf> syntax, too.
+
+Here's a short sample config:
+
+ AddType voltage-in in
+ AddType voltage-out out
+ Interval 300
+ Script /usr/lib/munin/plugins/nut
+
+The options have the following semantic (i.E<nbsp>e. meaning):
+
+=over 4
+
+=item B<AddType> I<to> I<from> [I<from> ...]
+
+collectd uses B<types> to specify how data is structured. In Munin all data is
+structured the same way, so some way of telling collectd how to handle the data
+is needed. This option translates the so called "field names" of Munin to the
+"types" of collectd. If more than one field are of the same type, e.E<nbsp>g.
+the C<nut> plugin above provides C<in> and C<out> which are both voltages, you
+can use a hyphen to add a "type instance" to the type.
+
+For a list of already defined "types" look at the F<types.db> file in
+collectd's library path, e.E<nbsp>g. F</usr/lib/collectd/>.
+
+=item B<Interval> I<Seconds>
+
+Sets the interval in which the plugins are executed. This doesn't need to match
+the interval setting of the collectd daemon. Usually, you want to execute the
+Munin plugins much less often, e.E<nbsp>g. every 300 seconds versus every 10
+seconds.
+
+=item B<Script> I<File>
+
+Adds a script to the list of scripts to be executed once per I<Interval>
+seconds.
+
+=back
+
+=cut
+
+sub handle_config_addtype
+{
+ my $list = shift;
+
+ for (my $i = 0; $i < @$list; $i++)
+ {
+ my ($to, @from) = split (' ', $list->[$i]);
+ for (my $j = 0; $j < @from; $j++)
+ {
+ $TypeMap->{$from[$j]} = $to;
+ }
+ }
+} # handle_config_addtype
+
+sub handle_config_script
+{
+ my $scripts = shift;
+
+ for (my $i = 0; $i < @$scripts; $i++)
+ {
+ my $script = $scripts->[$i];
+ if (!-e $script)
+ {
+ print STDERR "Script `$script' doesn't exist.\n";
+ }
+ elsif (!-x $script)
+ {
+ print STDERR "Script `$script' exists but is not executable.\n";
+ }
+ else
+ {
+ push (@$Scripts, $script);
+ }
+ } # for $i
+} # handle_config_script
+
+sub handle_config
+{
+ my $config = shift;
+
+ if (defined ($config->{'addtype'}))
+ {
+ if (ref ($config->{'addtype'}) eq 'ARRAY')
+ {
+ handle_config_addtype ($config->{'addtype'});
+ }
+ elsif (ref ($config->{'addtype'}) eq '')
+ {
+ handle_config_addtype ([$config->{'addtype'}]);
+ }
+ else
+ {
+ print STDERR "Cannot handle ref type '"
+ . ref ($config->{'addtype'}) . "' for option 'AddType'.\n";
+ }
+ }
+
+ if (defined ($config->{'script'}))
+ {
+ if (ref ($config->{'script'}) eq 'ARRAY')
+ {
+ handle_config_script ($config->{'script'});
+ }
+ elsif (ref ($config->{'script'}) eq '')
+ {
+ handle_config_addtype ([$config->{'script'}]);
+ }
+ else
+ {
+ print STDERR "Cannot handle ref type '"
+ . ref ($config->{'script'}) . "' for option 'Script'.\n";
+ }
+ }
+
+ if (defined ($config->{'interval'})
+ && (ref ($config->{'interval'}) eq ''))
+ {
+ my $num = int ($config->{'interval'});
+ if ($num > 0)
+ {
+ $Interval = $num;
+ }
+ }
+} # handle_config }}}
+
+sub execute_script
+{
+ my $fh;
+ my $pinst;
+ my $time = time ();
+ my $script = shift;
+ my $host = hostname () || 'localhost';
+ if (!open ($fh, '-|', $script))
+ {
+ print STDERR "Cannot execute $script: $!";
+ return;
+ }
+
+ $pinst = basename ($script);
+
+ while (my $line = <$fh>)
+ {
+ chomp ($line);
+ if ($line =~ m#^([^\.\-/]+)\.value\s+($RE{num}{real})#)
+ {
+ my $field = $1;
+ my $value = $2;
+ my $type = (defined ($TypeMap->{$field})) ? $TypeMap->{$field} : $field;
+
+ print "$host/munin-$pinst/$type interval=$Interval $time:$value\n";
+ }
+ }
+
+ close ($fh);
+} # execute_script
+
+sub main
+{
+ my $last_run;
+ my $next_run;
+
+ my %config = ParseConfig (-ConfigFile => $ConfigFile,
+ -AutoTrue => 1,
+ -LowerCaseNames => 1);
+ handle_config (\%config);
+
+ while (42)
+ {
+ $last_run = time ();
+ $next_run = $last_run + $Interval;
+
+ for (@$Scripts)
+ {
+ execute_script ($_);
+ }
+
+ while ((my $timeleft = ($next_run - time ())) > 0)
+ {
+ sleep ($timeleft);
+ }
+ }
+} # main
+
+=head1 REQUIREMENTS
+
+This script requires the following Perl modules to be installed:
+
+=over 4
+
+=item C<Config::General>
+
+=item C<Regexp::Common>
+
+=back
+
+=head1 SEE ALSO
+
+L<http://munin.projects.linpro.no/>,
+L<http://collectd.org/>,
+L<collectd-exec(5)>
+
+=head1 AUTHOR
+
+Florian octo Forster E<lt>octo at verplant.orgE<gt>
+
+=cut
+
+# vim: set sw=2 sts=2 ts=8 fdm=marker :