X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=bindings%2Fperl%2FCollectd.pm;h=cca349ec7a2c60e9a43dfa4b7030ce2299837d79;hb=3f2f61c7d74d9204405a4b0c21390451c98665a7;hp=fd5632a47d53a8d26509ab6bcaa1cf1eeb9ee06d;hpb=83149d73b8a3bd4889517a2e4d0adca0a52e7a06;p=collectd.git diff --git a/bindings/perl/Collectd.pm b/bindings/perl/Collectd.pm index fd5632a4..cca349ec 100644 --- a/bindings/perl/Collectd.pm +++ b/bindings/perl/Collectd.pm @@ -1,5 +1,5 @@ # collectd - Collectd.pm -# Copyright (C) 2007 Sebastian Harl +# Copyright (C) 2007, 2008 Sebastian Harl # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -22,6 +22,17 @@ package Collectd; use strict; use warnings; +use Config; + +use threads; +use threads::shared; + +BEGIN { + if (! $Config{'useithreads'}) { + die "Perl does not support ithreads!"; + } +} + require Exporter; our @ISA = qw( Exporter ); @@ -31,6 +42,10 @@ our %EXPORT_TAGS = ( plugin_register plugin_unregister plugin_dispatch_values + plugin_flush + plugin_flush_one + plugin_flush_all + plugin_dispatch_notification plugin_log ) ], 'types' => [ qw( @@ -39,6 +54,8 @@ our %EXPORT_TAGS = ( TYPE_WRITE TYPE_SHUTDOWN TYPE_LOG + TYPE_NOTIF + TYPE_FLUSH TYPE_DATASET ) ], 'ds_types' => [ qw( @@ -57,6 +74,15 @@ our %EXPORT_TAGS = ( LOG_INFO LOG_DEBUG ) ], + 'notif' => [ qw( + NOTIF_FAILURE + NOTIF_WARNING + NOTIF_OKAY + ) ], + 'globals' => [ qw( + $hostname_g + $interval_g + ) ], ); { @@ -65,21 +91,26 @@ our %EXPORT_TAGS = ( foreach keys %EXPORT_TAGS; } +# global variables +our $hostname_g; +our $interval_g; + Exporter::export_ok_tags ('all'); -my @plugins = (); -my @datasets = (); +my @plugins : shared = (); my %types = ( TYPE_INIT, "init", TYPE_READ, "read", TYPE_WRITE, "write", TYPE_SHUTDOWN, "shutdown", - TYPE_LOG, "log" + TYPE_LOG, "log", + TYPE_NOTIF, "notify", + TYPE_FLUSH, "flush" ); foreach my $type (keys %types) { - $plugins[$type] = {}; + $plugins[$type] = &share ({}); } sub _log { @@ -102,6 +133,8 @@ sub DEBUG { _log (scalar caller, LOG_DEBUG, shift); } sub plugin_call_all { my $type = shift; + our $cb_name = undef; + if (! defined $type) { return; } @@ -115,21 +148,47 @@ sub plugin_call_all { return; } + lock @plugins; foreach my $plugin (keys %{$plugins[$type]}) { my $p = $plugins[$type]->{$plugin}; + my $status = 0; + if ($p->{'wait_left'} > 0) { - # TODO: use interval_g - $p->{'wait_left'} -= 10; + $p->{'wait_left'} -= $interval_g; } next if ($p->{'wait_left'} > 0); - if (my $status = $p->{'code'}->(@_)) { + $cb_name = $p->{'cb_name'}; + $status = call_by_name (@_); + + if (! $status) { + my $err = undef; + + if ($@) { + $err = $@; + } + else { + $err = "callback returned false"; + } + + if (TYPE_LOG != $type) { + ERROR ("Execution of callback \"$cb_name\" failed: $err"); + } + + $status = 0; + } + + if ($status) { $p->{'wait_left'} = 0; - $p->{'wait_time'} = 10; + $p->{'wait_time'} = $interval_g; } elsif (TYPE_READ == $type) { + if ($p->{'wait_time'} < $interval_g) { + $p->{'wait_time'} = $interval_g; + } + $p->{'wait_left'} = $p->{'wait_time'}; $p->{'wait_time'} *= 2; @@ -141,12 +200,12 @@ sub plugin_call_all { . "Will suspend it for $p->{'wait_left'} seconds."); } elsif (TYPE_INIT == $type) { + ERROR ("${plugin}->init() failed with status $status. " + . "Plugin will be disabled."); + foreach my $type (keys %types) { plugin_unregister ($type, $plugin); } - - ERROR ("${plugin}->init() failed with status $status. " - . "Plugin will be disabled."); } elsif (TYPE_LOG != $type) { WARNING ("${plugin}->$types{$type}() failed with status $status."); @@ -187,13 +246,23 @@ sub plugin_register { if ((TYPE_DATASET == $type) && ("ARRAY" eq ref $data)) { return plugin_register_data_set ($name, $data); } - elsif ("CODE" eq ref $data) { - # TODO: make interval_g available at configuration time - $plugins[$type]->{$name} = { - wait_time => 10, - wait_left => 0, - code => $data, - }; + elsif ((TYPE_DATASET != $type) && (! ref $data)) { + my $pkg = scalar caller; + + my %p : shared; + + if ($data !~ m/^$pkg\:\:/) { + $data = $pkg . "::" . $data; + } + + %p = ( + wait_time => $interval_g, + wait_left => 0, + cb_name => $data, + ); + + lock @plugins; + $plugins[$type]->{$name} = \%p; } else { ERROR ("Collectd::plugin_register: Invalid data."); @@ -217,6 +286,7 @@ sub plugin_unregister { return plugin_unregister_data_set ($name); } elsif (defined $plugins[$type]) { + lock @plugins; delete $plugins[$type]->{$name}; } else { @@ -225,6 +295,34 @@ sub plugin_unregister { } } +sub plugin_flush { + my %args = @_; + + my $timeout = -1; + + DEBUG ("Collectd::plugin_flush:" + . (defined ($args{'timeout'}) ? " timeout = $args{'timeout'}" : "") + . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : "")); + + if (defined ($args{'timeout'}) && ($args{'timeout'} > 0)) { + $timeout = $args{'timeout'}; + } + + if (! defined $args{'plugins'}) { + plugin_flush_all ($timeout); + } + else { + if ("ARRAY" eq ref ($args{'plugins'})) { + foreach my $plugin (@{$args{'plugins'}}) { + plugin_flush_one ($timeout, $plugin); + } + } + else { + plugin_flush_one ($timeout, $args{'plugins'}); + } + } +} + 1; # vim: set sw=4 ts=4 tw=78 noexpandtab :