From b7c7c17f94c7d8d69510d9b19f3aa39711f7955f Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 9 Feb 2009 21:07:31 +0100 Subject: [PATCH] perl plugin / Collectd.pm: Export plugin_write() to Perl. plugin_write() accepts, just like the C counterpart, three arguments, 'plugins', 'datasets' and 'valuelists'. In contrast to the C implementation, all three arguments may either be a single scalar or a reference to an array - just like the 'plugins' and 'identifiers' arguments of the Perl implementation of plugin_flush(). --- bindings/perl/Collectd.pm | 61 +++++++++++++++++++++++++++++++ src/collectd-perl.pod | 16 ++++++++- src/perl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) diff --git a/bindings/perl/Collectd.pm b/bindings/perl/Collectd.pm index 738206bb..6e53b0e7 100644 --- a/bindings/perl/Collectd.pm +++ b/bindings/perl/Collectd.pm @@ -42,6 +42,7 @@ our %EXPORT_TAGS = ( plugin_register plugin_unregister plugin_dispatch_values + plugin_write plugin_flush plugin_flush_one plugin_flush_all @@ -318,6 +319,66 @@ sub plugin_unregister { } } +sub plugin_write { + my %args = @_; + + my @plugins = (); + my @datasets = (); + my @valuelists = (); + + if (! defined $args{'valuelists'}) { + ERROR ("Collectd::plugin_write: Missing 'valuelists' argument."); + return; + } + + DEBUG ("Collectd::plugin_write:" + . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : "") + . (defined ($args{'datasets'}) ? " datasets = $args{'datasets'}" : "") + . " valueslists = $args{'valuelists'}"); + + if (defined ($args{'plugins'})) { + if ("ARRAY" eq ref ($args{'plugins'})) { + @plugins = @{$args{'plugins'}}; + } + else { + @plugins = ($args{'plugins'}); + } + } + else { + @plugins = (undef); + } + + if ("ARRAY" eq ref ($args{'valuelists'})) { + @valuelists = @{$args{'valuelists'}}; + } + else { + @valuelists = ($args{'valuelists'}); + } + + if (defined ($args{'datasets'})) { + if ("ARRAY" eq ref ($args{'datasets'})) { + @datasets = @{$args{'datasets'}}; + } + else { + @datasets = ($args{'datasets'}); + } + } + else { + @datasets = (undef) x scalar (@valuelists); + } + + if ($#datasets != $#valuelists) { + ERROR ("Collectd::plugin_write: Invalid number of datasets."); + return; + } + + foreach my $plugin (@plugins) { + for (my $i = 0; $i < scalar (@valuelists); ++$i) { + _plugin_write ($plugin, $datasets[$i], $valuelists[$i]); + } + } +} + sub plugin_flush { my %args = @_; diff --git a/src/collectd-perl.pod b/src/collectd-perl.pod index c3fcb108..18dbafdc 100644 --- a/src/collectd-perl.pod +++ b/src/collectd-perl.pod @@ -341,12 +341,26 @@ as the first argument to B. This syntax is still supported for backwards compatibility but has been deprecated and will be removed in some future version of collectd. +=item B ([B => I<...>][, B => I<...>], +B => I<...>) + +Calls the write function of the given I with the provided I and I. In contrast to B, it does +not update collectd's internal cache and bypasses the filter mechanism (see +L for details). If the B argument has been omitted, +the values will be dispatched to all registered write plugins. If the +B argument has been omitted, the required data sets are looked up +according to the C member in the appropriate value list. The value of +all three arguments may either be a single scalar or a reference to an array. +If the B argument has been specified, the number of data sets has to +equal the number of specified value lists. + =item B ([B => I][, B => I<...>][, B => I<...>]) Flush one or more plugins. I and the specified I are passed on to the registered flush-callbacks. If omitted, the timeout defaults -to C<-1>. The identifier defaults to the undefined value. If the I +to C<-1>. The identifier defaults to the undefined value. If the B argument has been specified, only named plugins will be flushed. The value of the B and B arguments may either be a string or a reference to an array of strings. diff --git a/src/perl.c b/src/perl.c index 2d4cc867..9413d2cb 100644 --- a/src/perl.c +++ b/src/perl.c @@ -85,6 +85,7 @@ void boot_DynaLoader (PerlInterpreter *, CV *); static XS (Collectd_plugin_register_ds); static XS (Collectd_plugin_unregister_ds); static XS (Collectd_plugin_dispatch_values); +static XS (Collectd__plugin_write); static XS (Collectd__plugin_flush); static XS (Collectd_plugin_dispatch_notification); static XS (Collectd_plugin_log); @@ -139,6 +140,7 @@ static struct { { "Collectd::plugin_register_data_set", Collectd_plugin_register_ds }, { "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds }, { "Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values }, + { "Collectd::_plugin_write", Collectd__plugin_write }, { "Collectd::_plugin_flush", Collectd__plugin_flush }, { "Collectd::plugin_dispatch_notification", Collectd_plugin_dispatch_notification }, @@ -737,6 +739,37 @@ static int pplugin_dispatch_values (pTHX_ HV *values) } /* static int pplugin_dispatch_values (char *, HV *) */ /* + * Submit the values to a single write function. + */ +static int pplugin_write (pTHX_ const char *plugin, AV *data_set, HV *values) +{ + data_set_t ds; + value_list_t vl = VALUE_LIST_INIT; + + int ret; + + if (NULL == values) + return -1; + + if (0 != hv2value_list (aTHX_ values, &vl)) + return -1; + + if ((NULL != data_set) + && (0 != av2data_set (aTHX_ data_set, vl.type, &ds))) + return -1; + + ret = plugin_write (plugin, NULL == data_set ? NULL : &ds, &vl); + if (0 != ret) + log_warn ("Dispatching value to plugin \"%s\" failed with status %i.", + NULL == plugin ? "" : plugin, ret); + + if (NULL != data_set) + sfree (ds.ds); + sfree (vl.values); + return ret; +} /* static int pplugin_write (const char *plugin, HV *, HV *) */ + +/* * Dispatch a notification. */ static int pplugin_dispatch_notification (pTHX_ HV *notif) @@ -1021,6 +1054,65 @@ static XS (Collectd_plugin_dispatch_values) XSRETURN_EMPTY; } /* static XS (Collectd_plugin_dispatch_values) */ +/* Collectd::plugin_write (plugin, ds, vl). + * + * plugin: + * name of the plugin to call, may be 'undef' + * + * ds: + * data-set that describes the submitted values, may be 'undef' + * + * vl: + * value-list to be written + */ +static XS (Collectd__plugin_write) +{ + char *plugin; + SV *ds, *vl; + AV *ds_array; + + int ret; + + dXSARGS; + + if (3 != items) { + log_err ("Usage: Collectd::plugin_write(plugin, ds, vl)"); + XSRETURN_EMPTY; + } + + log_debug ("Collectd::plugin_write: plugin=\"%s\", ds=\"%s\", vl=\"%s\"", + SvPV_nolen (ST (0)), SvOK (ST (1)) ? SvPV_nolen (ST (1)) : "", + SvPV_nolen (ST (2))); + + if (! SvOK (ST (0))) + plugin = NULL; + else + plugin = SvPV_nolen (ST (0)); + + ds = ST (1); + if (SvROK (ds) && (SVt_PVAV == SvTYPE (SvRV (ds)))) + ds_array = (AV *)SvRV (ds); + else if (! SvOK (ds)) + ds_array = NULL; + else { + log_err ("Collectd::plugin_write: Invalid data-set."); + XSRETURN_EMPTY; + } + + vl = ST (2); + if (! (SvROK (vl) && (SVt_PVHV == SvTYPE (SvRV (vl))))) { + log_err ("Collectd::plugin_write: Invalid value-list."); + XSRETURN_EMPTY; + } + + ret = pplugin_write (aTHX_ plugin, ds_array, (HV *)SvRV (vl)); + + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; +} /* static XS (Collectd__plugin_write) */ + /* * Collectd::_plugin_flush (plugin, timeout, identifier). * -- 2.11.0