Merge branch 'collectd-5.0'
authorFlorian Forster <octo@collectd.org>
Sun, 27 Mar 2011 17:06:47 +0000 (10:06 -0700)
committerFlorian Forster <octo@collectd.org>
Sun, 27 Mar 2011 17:06:47 +0000 (10:06 -0700)
ChangeLog
src/collectd.conf.pod
src/filter_chain.c
src/libvirt.c
src/plugin.c
src/plugin.h
src/processes.c
src/python.c

index 91a8ef9..234a311 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-yyyy-mm-dd, Version 5.0.0
+2011-03-28, Version 5.0.0
        * collectd: The "FQDNLookup" option is now enabled by default.
        * collectd: The internal representation of time has been changed to
          allow a higher accuracy than one second.
@@ -68,6 +68,24 @@ yyyy-mm-dd, Version 5.0.0
        * v5upgrade target: Target for converting v4 data sets to the v5
          schema.
 
+2011-03-26, Version 4.10.3
+       * Documentation: Several updates and additions. Thanks to Sebastian Harl.
+       * collectd: Build issues (compiler warnings) have been fixed. Thanks to
+         Bruno Prémont.
+       * collectd: Threshold subsection: Handling of NAN values in the
+         percentage calculation has been fixed.
+       * collectd, java plugin, ntpd plugin: Several diagnostic messages have
+         been improved.
+       * curl_json plugin: Handling of arrays has been fixed.
+       * libvirt plugin: A bug in reading the virtual CPU statistics has been
+         fixed. Thanks to “JLPC” for reporting this problem.
+       * modbus plugin: Compatibility with libmodbus 2.0.3 has been restored.
+       * processes plugin: Potentially erroneous behavior has been fixed in an
+         error handling case.
+       * python plugin: Fix dispatching of values from Python scripts to
+         collectd. Thanks to Gregory Szorc for finding and fixing this
+         problem.
+
 2010-11-27, Version 4.10.2
        * Documentation: Various documentation fixes.
        * collectd: If including one configuration file fails, continue with
@@ -176,6 +194,22 @@ yyyy-mm-dd, Version 5.0.0
        * regex match: The "Invert" option has been added. Thanks to Julien
          Ammous for his patch.
 
+2011-03-26, Version 4.9.5
+       * Documentation: Several updates and additions. Thanks to Sebastian Harl.
+       * collectd: Build issues (compiler warnings) have been fixed. Thanks to
+         Bruno Prémont.
+       * collectd: Threshold subsection: Handling of NAN values in the
+         percentage calculation has been fixed.
+       * collectd, java plugin, ntpd plugin: Several diagnostic messages have
+         been improved.
+       * libvirt plugin: A bug in reading the virtual CPU statistics has been
+         fixed. Thanks to “JLPC” for reporting this problem.
+       * processes plugin: Potentially erroneous behavior has been fixed in an
+         error handling case.
+       * python plugin: Fix dispatching of values from Python scripts to
+         collectd. Thanks to Gregory Szorc for finding and fixing this
+         problem.
+
 2010-11-27, Version 4.9.4
        * Documentation: Various documentation fixes.
        * collectd: If including one configuration file fails, continue with
index ed979c4..b0f8dfe 100644 (file)
@@ -2063,8 +2063,10 @@ Hostname of the database server. Defaults to B<localhost>.
 =item B<User> I<Username>
 
 Username to use when connecting to the database. The user does not have to be
-granted any privileges (which is synonym to granting the C<USAGE> privilege).
-Any existing MySQL user will do.
+granted any privileges (which is synonym to granting the C<USAGE> privilege),
+unless you want to collectd replication statistics (see B<MasterStats> and
+B<SlaveStats> below). In this case, the user needs the C<REPLICATION CLIENT>
+(or C<SUPER>) privileges. Else, any existing MySQL user will do.
 
 =item B<Password> I<Password>
 
@@ -2096,7 +2098,9 @@ C<mysql_real_connect> function for details.
 
 =item B<SlaveStats> I<true|false>
 
-Enable the collection of master / slave statistics in a replication setup.
+Enable the collection of master / slave statistics in a replication setup. In
+order to be able to get access to these statistics, the user needs special
+privileges. See the B<User> documentation above.
 
 =item B<SlaveNotifications> I<true|false>
 
@@ -2854,7 +2858,8 @@ and are checked by default depends on the distribution you use.
 This plugin sends a desktop notification to a notification daemon, as defined
 in the Desktop Notification Specification. To actually display the
 notifications, B<notification-daemon> is required and B<collectd> has to be
-able to access the X server.
+able to access the X server (i.E<nbsp>e., the C<DISPLAY> and C<XAUTHORITY>
+environment variables have to be set correctly) and the D-Bus message bus.
 
 The Desktop Notification Specification can be found at
 L<http://www.galago-project.org/specs/notification/>.
index 4b164dc..ed2df61 100644 (file)
@@ -22,6 +22,7 @@
 #include "collectd.h"
 #include "configfile.h"
 #include "plugin.h"
+#include "utils_complain.h"
 #include "common.h"
 #include "filter_chain.h"
 
@@ -692,10 +693,15 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
 
   if ((plugin_list == NULL) || (plugin_list[0] == NULL))
   {
+    static c_complain_t enoent_complaint = C_COMPLAIN_INIT_STATIC;
+
     status = plugin_write (/* plugin = */ NULL, ds, vl);
     if (status == ENOENT)
     {
-      INFO ("Filter subsystem: Built-in target `write': Dispatching value to "
+      /* in most cases this is a permanent error, so use the complain
+       * mechanism rather than spamming the logs */
+      c_complain (LOG_INFO, &enoent_complaint,
+          "Filter subsystem: Built-in target `write': Dispatching value to "
           "all write plugins failed with status %i (ENOENT). "
           "Most likely this means you didn't load any write plugins.",
           status);
@@ -705,6 +711,13 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
       INFO ("Filter subsystem: Built-in target `write': Dispatching value to "
           "all write plugins failed with status %i.", status);
     }
+    else
+    {
+      assert (status == 0);
+      c_release (LOG_INFO, &enoent_complaint, "Filter subsystem: "
+          "Built-in target `write': Some write plugin is back to normal "
+          "operation. `write' succeeded.");
+    }
   }
   else
   {
index b5e7e99..c74b937 100644 (file)
@@ -413,22 +413,32 @@ lv_read (void)
     for (i = 0; i < nr_domains; ++i) {
         virDomainInfo info;
         virVcpuInfoPtr vinfo = NULL;
+        int status;
         int j;
 
-        if (virDomainGetInfo (domains[i], &info) != 0)
+        status = virDomainGetInfo (domains[i], &info);
+        if (status != 0)
+        {
+            ERROR ("libvirt plugin: virDomainGetInfo failed with status %i.",
+                    status);
             continue;
+        }
 
         cpu_submit (info.cpuTime, domains[i], "virt_cpu_total");
 
-        vinfo = malloc (info.nrVirtCpu * sizeof vinfo[0]);
+        vinfo = malloc (info.nrVirtCpu * sizeof (vinfo[0]));
         if (vinfo == NULL) {
             ERROR ("libvirt plugin: malloc failed.");
             continue;
         }
 
-        if (virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu,
-                    NULL, 0) != 0) {
-            sfree (vinfo);
+        status = virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu,
+                /* cpu map = */ NULL, /* cpu map length = */ 0);
+        if (status < 0)
+        {
+            ERROR ("libvirt plugin: virDomainGetVcpus failed with status %i.",
+                    status);
+            free (vinfo);
             continue;
         }
 
index 9ecee5c..89a2e00 100644 (file)
@@ -280,8 +280,6 @@ static int plugin_load_file (char *file, uint32_t flags)
        lt_dlhandle dlh;
        void (*reg_handle) (void);
 
-       DEBUG ("file = %s", file);
-
        lt_dlinit ();
        lt_dlerror (); /* clear errors */
 
@@ -297,23 +295,35 @@ static int plugin_load_file (char *file, uint32_t flags)
        }
 #else /* if LIBTOOL_VERSION == 1 */
        if (flags & PLUGIN_FLAGS_GLOBAL)
-               ERROR ("plugin_load_file: The global flag is not supported, "
+               WARNING ("plugin_load_file: The global flag is not supported, "
                                "libtool 2 is required for this.");
        dlh = lt_dlopen (file);
 #endif
 
        if (dlh == NULL)
        {
-               const char *error = lt_dlerror ();
+               char errbuf[1024] = "";
+
+               ssnprintf (errbuf, sizeof (errbuf),
+                               "lt_dlopen (\"%s\") failed: %s. "
+                               "The most common cause for this problem are "
+                               "missing dependencies. Use ldd(1) to check "
+                               "the dependencies of the plugin "
+                               "/ shared object.",
+                               file, lt_dlerror ());
+
+               ERROR ("%s", errbuf);
+               /* Make sure this is printed to STDERR in any case, but also
+                * make sure it's printed only once. */
+               if (list_log != NULL)
+                       fprintf (stderr, "ERROR: %s\n", errbuf);
 
-               ERROR ("lt_dlopen (%s) failed: %s", file, error);
-               fprintf (stderr, "lt_dlopen (%s) failed: %s\n", file, error);
                return (1);
        }
 
        if ((reg_handle = (void (*) (void)) lt_dlsym (dlh, "module_register")) == NULL)
        {
-               WARNING ("Couldn't find symbol `module_register' in `%s': %s\n",
+               WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n",
                                file, lt_dlerror ());
                lt_dlclose (dlh);
                return (-1);
@@ -862,7 +872,7 @@ int plugin_register_missing (const char *name,
                                (void *) callback, ud));
 } /* int plugin_register_missing */
 
-int plugin_register_shutdown (char *name,
+int plugin_register_shutdown (const char *name,
                int (*callback) (void))
 {
        return (create_register_callback (&list_shutdown, name,
index 4d5201b..e880472 100644 (file)
@@ -281,7 +281,7 @@ int plugin_register_flush (const char *name,
                plugin_flush_cb callback, user_data_t *user_data);
 int plugin_register_missing (const char *name,
                plugin_missing_cb callback, user_data_t *user_data);
-int plugin_register_shutdown (char *name,
+int plugin_register_shutdown (const char *name,
                plugin_shutdown_cb callback);
 int plugin_register_data_set (const data_set_t *ds);
 int plugin_register_log (const char *name,
index 655cddb..72442f0 100644 (file)
@@ -1594,9 +1594,9 @@ static int ps_read (void)
        procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count);
        if (procs == NULL)
        {
-               kvm_close (kd);
                ERROR ("processes plugin: Cannot get kvm processes list: %s",
                                kvm_geterr(kd));
+               kvm_close (kd);
                return (0);
        }
 
index eed0591..ee67388 100644 (file)
@@ -345,26 +345,26 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        CPY_RETURN_FROM_THREADS 0;
                }
                for (i = 0; i < value_list->values_len; ++i) {
-                       if (ds->ds->type == DS_TYPE_COUNTER) {
+                       if (ds->ds[i].type == DS_TYPE_COUNTER) {
                                if ((long) value_list->values[i].counter == value_list->values[i].counter)
                                        PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].counter));
                                else
                                        PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
-                       } else if (ds->ds->type == DS_TYPE_GAUGE) {
+                       } else if (ds->ds[i].type == DS_TYPE_GAUGE) {
                                PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge));
-                       } else if (ds->ds->type == DS_TYPE_DERIVE) {
+                       } else if (ds->ds[i].type == DS_TYPE_DERIVE) {
                                if ((long) value_list->values[i].derive == value_list->values[i].derive)
                                        PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].derive));
                                else
                                        PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
-                       } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+                       } else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) {
                                if ((long) value_list->values[i].absolute == value_list->values[i].absolute)
                                        PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].absolute));
                                else
                                        PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
                        } else {
                                Py_BEGIN_ALLOW_THREADS
-                               ERROR("cpy_write_callback: Unknown value type %d.", ds->ds->type);
+                               ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type);
                                Py_END_ALLOW_THREADS
                                Py_DECREF(list);
                                CPY_RETURN_FROM_THREADS 0;