src/daemon/plugin.[ch]: Use cdtime_t for the interval argument of "register complex...
[collectd.git] / src / daemon / plugin.c
index 6c6ab63..b3cb97f 100644 (file)
@@ -307,6 +307,56 @@ static int register_callback (llist_t **list, /* {{{ */
        return (0);
 } /* }}} int register_callback */
 
+static void log_list_callbacks (llist_t **list, /* {{{ */
+                               const char *comment)
+{
+       char *str;
+       int len;
+       llentry_t *le;
+       int i;
+       int n;
+       char **keys;
+
+       n = llist_size(*list);
+       if (n == 0)
+       {
+               INFO("%s [none]", comment);
+               return;
+       }
+
+       keys = calloc(n, sizeof(char*));
+
+       if (keys == NULL)
+       {
+               ERROR("%s: failed to allocate memory for list of callbacks",
+                     comment);
+
+               return;
+       }
+
+       for (le = llist_head (*list), i = 0, len = 0;
+            le != NULL;
+            le = le->next, i++)
+       {
+               keys[i] = le->key;
+               len += strlen(le->key) + 6;
+       }
+       str = malloc(len + 10);
+       if (str == NULL)
+       {
+               ERROR("%s: failed to allocate memory for list of callbacks",
+                     comment);
+       }
+       else
+       {
+               *str = '\0';
+               strjoin(str, len, keys, n, "', '");
+               INFO("%s ['%s']", comment, str);
+               free(str);
+       }
+       free(keys);
+} /* }}} void log_list_callbacks */
+
 static int create_register_callback (llist_t **list, /* {{{ */
                const char *name, void *callback, user_data_t *ud)
 {
@@ -949,7 +999,6 @@ int plugin_load (char const *plugin_name, uint32_t flags)
        const char *dir;
        char  filename[BUFSIZE] = "";
        char  typename[BUFSIZE];
-       int   typename_len;
        int   ret;
        struct stat    statbuf;
        struct dirent *de;
@@ -989,7 +1038,6 @@ int plugin_load (char const *plugin_name, uint32_t flags)
                WARNING ("plugin_load: Filename too long: \"%s.so\"", plugin_name);
                return (-1);
        }
-       typename_len = strlen (typename);
 
        if ((dh = opendir (dir)) == NULL)
        {
@@ -1001,7 +1049,7 @@ int plugin_load (char const *plugin_name, uint32_t flags)
 
        while ((de = readdir (dh)) != NULL)
        {
-               if (strncasecmp (de->d_name, typename, typename_len))
+               if (strcasecmp (de->d_name, typename))
                        continue;
 
                status = ssnprintf (filename, sizeof (filename),
@@ -1197,7 +1245,7 @@ int plugin_register_read (const char *name,
 
 int plugin_register_complex_read (const char *group, const char *name,
                plugin_read_cb callback,
-               const struct timespec *interval,
+               cdtime_t interval,
                user_data_t *user_data)
 {
        read_func_t *rf;
@@ -1218,10 +1266,7 @@ int plugin_register_complex_read (const char *group, const char *name,
                rf->rf_group[0] = '\0';
        rf->rf_name = strdup (name);
        rf->rf_type = RF_COMPLEX;
-       if (interval != NULL)
-               rf->rf_interval = TIMESPEC_TO_CDTIME_T (interval);
-       else
-               rf->rf_interval = plugin_get_interval ();
+       rf->rf_interval = (interval != 0) ? interval : plugin_get_interval ();
 
        /* Set user data */
        if (user_data == NULL)
@@ -1400,6 +1445,11 @@ int plugin_unregister_read (const char *name) /* {{{ */
        return (0);
 } /* }}} int plugin_unregister_read */
 
+void plugin_log_available_writers (void)
+{
+       log_list_callbacks (&list_write, "Available write targets:");
+}
+
 static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */
 {
        read_func_t *rf    = e->value;
@@ -2162,7 +2212,7 @@ int plugin_dispatch_values (value_list_t const *vl)
 
 __attribute__((sentinel))
 int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */
-               _Bool store_percentage, ...)
+               _Bool store_percentage, int store_type, ...)
 {
        value_list_t *vl;
        int failed = 0;
@@ -2171,28 +2221,32 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */
 
        assert (template->values_len == 1);
 
-       va_start (ap, store_percentage);
-       while (42)
-       {
-               char const *name;
-               gauge_t value;
+  /* Calculate sum for Gauge to calculate percent if needed */
+       if (DS_TYPE_GAUGE == store_type)        {
+               va_start (ap, store_type);
+               while (42)
+               {
+                       char const *name;
+                       gauge_t value;
 
-               name = va_arg (ap, char const *);
-               if (name == NULL)
-                       break;
+                       name = va_arg (ap, char const *);
+                       if (name == NULL)
+                               break;
 
-               value = va_arg (ap, gauge_t);
-               if (!isnan (value))
-                       sum += value;
+                       value = va_arg (ap, gauge_t);
+                       if (!isnan (value))
+                               sum += value;
+               }
+               va_end (ap);
        }
-       va_end (ap);
+
 
        vl = plugin_value_list_clone (template);
        /* plugin_value_list_clone makes sure vl->time is set to non-zero. */
        if (store_percentage)
                sstrncpy (vl->type, "percent", sizeof (vl->type));
 
-       va_start (ap, store_percentage);
+       va_start (ap, store_type);
        while (42)
        {
                char const *name;
@@ -2205,9 +2259,27 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */
                sstrncpy (vl->type_instance, name, sizeof (vl->type_instance));
 
                /* Set the value. */
-               vl->values[0].gauge = va_arg (ap, gauge_t);
-               if (store_percentage)
-                       vl->values[0].gauge *= 100.0 / sum;
+               switch (store_type)
+               {
+               case DS_TYPE_GAUGE:
+                       vl->values[0].gauge = va_arg (ap, gauge_t);
+                       if (store_percentage)
+                               vl->values[0].gauge *= 100.0 / sum;
+                       break;
+               case DS_TYPE_ABSOLUTE:
+                       vl->values[0].absolute = va_arg (ap, absolute_t);
+                       break;
+               case DS_TYPE_COUNTER:
+                       vl->values[0].counter  = va_arg (ap, counter_t);
+                       break;
+               case DS_TYPE_DERIVE:
+                       vl->values[0].derive   = va_arg (ap, derive_t);
+                       break;
+               default:
+                       ERROR ("plugin_dispatch_multivalue: given store_type is incorrect.");
+                       failed++;
+               }
+
 
                status = plugin_write_enqueue (vl);
                if (status != 0)