src/configfile.c: s/TypesDS/TypesDB/;
[collectd.git] / src / perl.c
index 0c5e882..021d309 100644 (file)
@@ -56,6 +56,7 @@ void boot_DynaLoader (PerlInterpreter *, CV *);
 static XS (Collectd_plugin_register);
 static XS (Collectd_plugin_unregister);
 static XS (Collectd_plugin_dispatch_values);
+static XS (Collectd_plugin_log);
 
 
 /*
@@ -83,12 +84,15 @@ typedef struct {
 static const char *config_keys[] =
 {
        "LoadPlugin",
-       NULL
+       "BaseName",
+       "IncludeDir"
 };
-static int config_keys_num = 1;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
 static PerlInterpreter *perl = NULL;
 
+static char base_name[DATA_MAX_NAME_LEN] = "";
+
 static char *plugin_types[] = { "init", "read", "write", "shutdown" };
 static HV   *plugins[PLUGIN_TYPES];
 static HV   *data_sets;
@@ -101,6 +105,7 @@ static struct {
        { "Collectd::plugin_register",        Collectd_plugin_register },
        { "Collectd::plugin_unregister",      Collectd_plugin_unregister },
        { "Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values },
+       { "Collectd::plugin_log",             Collectd_plugin_log },
        { "", NULL }
 };
 
@@ -313,6 +318,18 @@ static int value_list2hv (value_list_t *vl, data_set_t *ds, HV *hash)
  * Internal functions.
  */
 
+static char *get_module_name (char *buf, size_t buf_len, const char *module) {
+       int status = 0;
+       if (base_name[0] == '\0')
+               status = snprintf (buf, buf_len, "%s", module);
+       else
+               status = snprintf (buf, buf_len, "%s::%s", base_name, module);
+       if ((status < 0) || (status >= buf_len))
+               return (NULL);
+       buf[buf_len] = '\0';
+       return (buf);
+} /* char *get_module_name */
+
 /*
  * Add a new plugin with the given name.
  */
@@ -506,6 +523,7 @@ static int pplugin_dispatch_values (char *name, HV *values)
 
        if (NULL != (tmp = Perl_hv_fetch (perl, values, "host", 4, 0))) {
                strncpy (list.host, SvPV_nolen (*tmp), DATA_MAX_NAME_LEN);
+               list.host[DATA_MAX_NAME_LEN - 1] = '\0';
        }
        else {
                strcpy (list.host, hostname_g);
@@ -615,8 +633,8 @@ static int pplugin_call (int type, char *name, SV *sub, va_list ap)
 
        /* prevent an endless loop */
        if (PLUGIN_LOG != type)
-               log_debug ("pplugin_call: executing Collectd::plugin::%s->%s()",
-                               name, plugin_types[type]);
+               log_debug ("pplugin_call: executing %s::%s->%s()",
+                               base_name, name, plugin_types[type]);
 
        retvals = Perl_call_sv (perl, sub, G_SCALAR | xflags);
 
@@ -624,8 +642,8 @@ static int pplugin_call (int type, char *name, SV *sub, va_list ap)
        if (1 > retvals) {
                if (PLUGIN_LOG != type)
                        log_warn ("pplugin_call: "
-                                       "Collectd::plugin::%s->%s() returned void - assuming true",
-                                       name, plugin_types[type]);
+                                       "%s::%s->%s() returned void - assuming true",
+                                       base_name, name, plugin_types[type]);
        }
        else {
                SV *tmp = POPs;
@@ -683,21 +701,20 @@ static int pplugin_call_all (int type, ...)
                        if (p->wait_time > 86400)
                                p->wait_time = 86400;
 
-                       log_warn ("Collectd::plugin::%s->read() failed. "
-                                       "Will suspend it for %i seconds.",
+                       log_warn ("%s->read() failed. Will suspend it for %i seconds.",
                                        plugin, p->wait_left);
                }
                else if (PLUGIN_INIT == type) {
                        int i = 0;
 
-                       log_err ("Collectd::plugin::%s->init() failed. "
-                                       "Plugin will be disabled.", plugin, status);
+                       log_err ("%s->init() failed. Plugin will be disabled.",
+                                       plugin, status);
 
                        for (i = 0; i < PLUGIN_TYPES; ++i)
                                pplugin_unregister (i, plugin);
                }
                else if (PLUGIN_LOG != type) {
-                       log_warn ("Collectd::plugin::%s->%s() failed with status %i.",
+                       log_warn ("%s->%s() failed with status %i.",
                                        plugin, plugin_types[type], status);
                }
 
@@ -825,7 +842,6 @@ static XS (Collectd_plugin_dispatch_values)
 
        dXSARGS;
 
-       items = 2;
        if (2 != items) {
                log_err ("Usage: Collectd::plugin_dispatch_values(name, values)");
                XSRETURN_EMPTY;
@@ -854,6 +870,30 @@ static XS (Collectd_plugin_dispatch_values)
 } /* static XS (Collectd_plugin_dispatch_values) */
 
 /*
+ * Collectd::plugin_log (level, message).
+ *
+ * level:
+ *   log level (LOG_DEBUG, ... LOG_ERR)
+ *
+ * message:
+ *   log message
+ */
+static XS (Collectd_plugin_log)
+{
+       dXSARGS;
+
+       if (2 != items) {
+               log_err ("Usage: Collectd::plugin_log(level, message)");
+               XSRETURN_EMPTY;
+       }
+
+       log_debug ("Collectd::plugin_log: level = %i, message = \"%s\"",
+                       SvIV (ST (0)), SvPV_nolen (ST (1)));
+       plugin_log (SvIV (ST (0)), SvPV_nolen (ST (1)));
+       XSRETURN_YES;
+} /* static XS (Collectd_plugin_log) */
+
+/*
  * Collectd::bootstrap ().
  */
 static XS (boot_Collectd)
@@ -915,12 +955,29 @@ static int perl_config (const char *key, const char *value)
        log_debug ("perl_config: key = \"%s\", value=\"%s\"", key, value);
 
        if (0 == strcasecmp (key, "LoadPlugin")) {
-               log_debug ("perl_config: loading perl plugin \"%s\"", value);
+               char module_name[DATA_MAX_NAME_LEN];
+
+               if (get_module_name (module_name, sizeof (module_name), value)
+                               == NULL) {
+                       log_err ("Invalid module name %s", value);
+                       return (1);
+               } /* if (get_module_name == NULL) */
 
+               log_debug ("perl_config: loading perl plugin \"%s\"", value);
                Perl_load_module (perl, PERL_LOADMOD_NOIMPORT,
-                               Perl_newSVpvf (perl, "Collectd::plugin::%s", value),
+                               Perl_newSVpv (perl, module_name, strlen (module_name)),
                                Nullsv);
        }
+       else if (0 == strcasecmp (key, "BaseName")) {
+               log_debug ("perl_config: Setting plugin basename to \"%s\"", value);
+               strncpy (base_name, value, sizeof (base_name));
+               base_name[sizeof (base_name) - 1] = '\0';
+       }
+       else if (0 == strcasecmp (key, "IncludeDir")) {
+               Perl_av_unshift (perl, GvAVn (PL_incgv), 1);
+               Perl_av_store (perl, GvAVn (PL_incgv),
+                               0, Perl_newSVpv (perl, value, strlen (value)));
+       }
        else {
                return -1;
        }
@@ -1045,7 +1102,9 @@ void module_register (void)
        plugin_register_log ("perl", perl_log);
        plugin_register_config ("perl", perl_config, config_keys, config_keys_num);
        plugin_register_init ("perl", perl_init);
+
        plugin_register_read ("perl", perl_read);
+
        plugin_register_write ("perl", perl_write);
        plugin_register_shutdown ("perl", perl_shutdown);
        return;