Merge branch 'collectd-5.6'
authorMarc Fournier <marc.fournier@camptocamp.com>
Mon, 10 Oct 2016 19:04:03 +0000 (21:04 +0200)
committerMarc Fournier <marc.fournier@camptocamp.com>
Mon, 10 Oct 2016 19:04:03 +0000 (21:04 +0200)
13 files changed:
ChangeLog
contrib/redhat/collectd.spec
src/Makefile.am
src/collectd-snmp.pod
src/collectd.conf.pod
src/daemon/common.c
src/lua.c
src/postgresql_default.conf
src/rrdcached.c
src/tail_csv.c
src/vserver.c
src/write_redis.c
version-gen.sh

index 5155954..ff7ce70 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2016-10-07, Version 5.6.1
+       * Build system: Unnecessary linking of the Write Graphite plugin with
+         libyajl has been removed. Thanks to Marc Fournier.
+         Debian#839771, #1976
+       * collectd: A bug in the "FlushInterval" option that caused a
+         segmentation fault in the Write HTTP plugin has been fixed. Thanks to
+         Florian Forster. #1954
+       * Apache plugin: A syntax error has been fixed. Thanks to Florian
+         Forster.
+       * cURL-JSON plugin: A segmentation fault that occurred when handling
+         JSON with unexpected structure has been fixed. Thanks to Florian
+         Forster. #1896
+       * PostgreSQL plugin: Handling of "NULL" values in the "query_plans" and
+         "query_plans_by_table" queries has been fixed. Thanks to Bernd
+         Zeimetz. #1905
+       * RRDCacheD plugin: Reconnection behavior has been added. Thanks to
+         Sebastian Harl. Debian#657877
+       * VServer plugin: Use of a deprecated API ("readdir_r()") has been
+         fixed. Thanks to Sebastian Harl.
+       * Write Graphite plugin: Make default values configurable at compile
+         time again. Thanks to Florian Forster. #1953
+       * Write HTTP plugin: A bug has been fixed that lead to flush callbacks
+         being registered twice. Thanks to Florian Forster. #1955
+
 2016-09-11, Version 5.6.0
        * Build system: An option to to avoid building the DF plugin against XFS
          has been added. Thanks to Ruben Kerkhof. #1878
index f66cb4a..eaf6f31 100644 (file)
 Summary:       Statistics collection and monitoring daemon
 Name:          collectd
 Version:       5.7.0
-Release:       2%{?dist}
+Release:       1%{?dist}
 URL:           https://collectd.org
 Source:                https://collectd.org/files/%{name}-%{version}.tar.bz2
 License:       GPLv2
@@ -2560,13 +2560,16 @@ fi
 %doc contrib/
 
 %changelog
-* Tue Aug 23 2016 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.0-1
+* Mon Oct 10 2016 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.0-1
 - New PRE-RELEASE version
 - New plugins enabled by default: hugepages
 - New plugins disabled by default: dpdkstat, intel_rdt
 
+* Mon Oct 10 2016 Victor Demonchy <v.demonchy@criteo.com> - 5.6.1-1
+- New upstream version
+
 * Sun Aug 14 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.6.0-1
-- New PRE-RELEASE version
+- New upstream version
 - New plugins enabled by default: chrony, cpusleep, gps, lua, mqtt, notify_nagios
 - New plugins disabled by default: grpc, xencpu, zone
 
index f48fdf3..344fcfd 100644 (file)
@@ -1273,7 +1273,6 @@ pkglib_LTLIBRARIES += write_graphite.la
 write_graphite_la_SOURCES = write_graphite.c \
                         utils_format_graphite.c utils_format_graphite.h
 write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_graphite_la_LIBADD = libformat_json.la
 endif
 
 if BUILD_PLUGIN_WRITE_HTTP
index 65a9b7c..c246f1d 100644 (file)
@@ -204,9 +204,9 @@ This value is not applied to counter-values.
 
 =item B<Ignore> I<Value> [, I<Value> ...]
 
-The ignore values allows to ignore Instances based on their name and the patterns
-specified by the various values you've entered. The match is a glob-type shell
-matching.
+The ignore values allows one to ignore Instances based on their name and the
+patterns specified by the various values you've entered. The match is a
+glob-type shell matching.
 
 =item B<InvertMatch> I<true|false(default)>
 
index 9f9dd93..1310c50 100644 (file)
@@ -960,7 +960,7 @@ support the SM Bus command subset).
 
 The reduction or normalization to mean sea level pressure requires (depending
 on selected method/approximation) also altitude and reference to temperature
-sensor(s).  When multiple temperature sensors are configured the minumum of
+sensor(s).  When multiple temperature sensors are configured the minimum of
 their values is always used (expecting that the warmer ones are affected by
 e.g. direct sun light at that moment).
 
@@ -1072,7 +1072,7 @@ The altitude (in meters) of the location where you meassure the pressure.
 
 Temperature sensor(s) which should be used as a reference when normalizing the
 pressure using C<Normalization> method 2.
-When specified more sensors a minumum is found and used each time.  The
+When specified more sensors a minimum is found and used each time.  The
 temperature reading directly from this pressure sensor/plugin is typically not
 suitable as the pressure sensor will be probably inside while we want outside
 temperature.  The collectd reference name is something like
@@ -2229,7 +2229,7 @@ is passed to them, so invalid settings here may go unnoticed. This is not the
 plugin's fault, it will report errors if it gets them from the libraryE<nbsp>/
 the driver. If a driver complains about an option, the plugin will dump a
 complete list of all options understood by that driver to the log. There is no
-way to programatically find out if an option expects a string or a numeric
+way to programmatically find out if an option expects a string or a numeric
 argument, so you will have to refer to the appropriate DBD's documentation to
 find this out. Sorry.
 
@@ -5958,7 +5958,7 @@ transaction fails or if the database server crashes.
 
 Specify the plugin instance name that should be used instead of the database
 name (which is the default, if this option has not been specified). This
-allows to query multiple databases of the same name on the same host (e.g.
+allows one to query multiple databases of the same name on the same host (e.g.
 when running multiple database server versions in parallel).
 The plugin instance name can also be set from the query result using
 the B<PluginInstanceFrom> option in B<Query> block.
@@ -6021,7 +6021,7 @@ Use SSL only.
 
 Specify the plugin instance name that should be used instead of the database
 name (which is the default, if this option has not been specified). This
-allows to query multiple databases of the same name on the same host (e.g.
+allows one to query multiple databases of the same name on the same host (e.g.
 when running multiple database server versions in parallel).
 
 =item B<KRBSrvName> I<kerberos_service_name>
@@ -6221,11 +6221,11 @@ below this limit.
 
 =item B<ProcessMatch> I<name> I<regex>
 
-Similar to the B<Process> option this allows to select more detailed
+Similar to the B<Process> option this allows one to select more detailed
 statistics of processes matching the specified I<regex> (see L<regex(7)> for
 details). The statistics of all matching processes are summed up and
 dispatched to the daemon using the specified I<name> as an identifier. This
-allows to "group" several processes together. I<name> must not contain
+allows one to "group" several processes together. I<name> must not contain
 slashes.
 
 =item B<CollectContextSwitch> I<Boolean>
@@ -6440,8 +6440,8 @@ C<collectd> anymore, it does not need to be flushed when C<collectd> is to be
 restarted. This results in much shorter (if any) gaps in graphs, especially
 under heavy load. Also, the C<rrdtool> command line utility is aware of the
 daemon so that it can flush values to disk automatically when needed. This
-allows to integrate automated flushing of values into graphing solutions much
-more easily.
+allows one to integrate automated flushing of values into graphing solutions
+much more easily.
 
 There are disadvantages, though: The daemon may reside on a different host, so
 it may not be possible for C<collectd> to create the appropriate RRD files
@@ -8275,7 +8275,7 @@ forwarded to the kafka producer library B<librdkafka>.
 
 =item B<Key> I<String>
 
-Use the specified string as a partioning key for the topic. Kafka breaks
+Use the specified string as a partitioning key for the topic. Kafka breaks
 topic into partitions and guarantees that for a given topology, the same
 consumer will be used for a specific key. The special (case insensitive)
 string B<Random> can be used to specify that an arbitrary partition should
index 654a5a0..c80abcb 100644 (file)
 extern kstat_ctl_t *kc;
 #endif
 
+/* AIX doesn't have MSG_DONTWAIT */
+#ifndef MSG_DONTWAIT
+#  define MSG_DONTWAIT MSG_NONBLOCK
+#endif
+
 #if !HAVE_GETPWNAM_R
 static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
@@ -1134,7 +1139,7 @@ int parse_value (const char *value_orig, value_t *ret_value, int ds_type)
   }
 
   if (value == endptr) {
-    ERROR ("parse_value: Failed to parse string as %s: %s.",
+    ERROR ("parse_value: Failed to parse string as %s: \"%s\".",
         DS_TYPE_TO_STRING (ds_type), value);
     sfree (value);
     return -1;
index d10b4ea..45fd7d5 100644 (file)
--- a/src/lua.c
+++ b/src/lua.c
@@ -543,7 +543,7 @@ static int lua_config_script(const oconfig_item_t *ci) /* {{{ */
   if (status != 0)
     return (status);
 
-  INFO("Lua plugin: File \"%s\" loaded succesfully", abs_path);
+  INFO("Lua plugin: File \"%s\" loaded successfully", abs_path);
 
   return 0;
 } /* }}} int lua_config_script */
index f905eb2..0aac41e 100644 (file)
 </Query>
 
 <Query query_plans>
-       Statement "SELECT sum(seq_scan) AS seq, \
-                       sum(seq_tup_read) AS seq_tup_read, \
-                       sum(idx_scan) AS idx, \
-                       sum(idx_tup_fetch) AS idx_tup_fetch \
+       Statement "SELECT coalesce(sum(seq_scan), 0) AS seq, \
+                         coalesce(sum(seq_tup_read), 0) AS seq_tup_read, \
+                         coalesce(sum(idx_scan), 0) AS idx, \
+                         coalesce(sum(idx_tup_fetch), 0) AS idx_tup_fetch \
                FROM pg_stat_user_tables;"
 
        <Result>
 
 <Query query_plans_by_table>
        Statement "SELECT schemaname, relname, \
-                       seq_scan AS seq, \
-                       seq_tup_read AS seq_tup_read, \
-                       idx_scan AS idx, \
-                       idx_tup_fetch AS idx_tup_fetch \
+                       coalesce(seq_scan, 0) AS seq, \
+                       coalesce(seq_tup_read, 0) AS seq_tup_read, \
+                       coalesce(idx_scan, 0) AS idx, \
+                       coalesce(idx_tup_fetch, 0) AS idx_tup_fetch \
                FROM pg_stat_user_tables;"
 
        <Result>
index 3db89b5..6d45ac9 100644 (file)
@@ -287,10 +287,31 @@ static int rc_config (oconfig_item_t *ci)
   return (0);
 } /* int rc_config */
 
+static int try_reconnect (void)
+{
+  int status;
+
+  rrdc_disconnect ();
+
+  rrd_clear_error ();
+  status = rrdc_connect (daemon_address);
+  if (status != 0)
+  {
+    ERROR ("rrdcached plugin: Failed to reconnect to RRDCacheD "
+        "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status);
+    return (-1);
+  }
+
+  INFO ("rrdcached plugin: Successfully reconnected to RRDCacheD "
+      "at %s", daemon_address);
+  return (0);
+} /* int try_reconnect */
+
 static int rc_read (void)
 {
   int status;
   rrdc_stats_t *head;
+  _Bool retried = 0;
 
   value_list_t vl = VALUE_LIST_INIT;
   vl.values = &(value_t) { .gauge = NAN };
@@ -307,19 +328,35 @@ static int rc_read (void)
     sstrncpy (vl.host, daemon_address, sizeof (vl.host));
   sstrncpy (vl.plugin, "rrdcached", sizeof (vl.plugin));
 
+  rrd_clear_error ();
   status = rrdc_connect (daemon_address);
   if (status != 0)
   {
-    ERROR ("rrdcached plugin: rrdc_connect (%s) failed with status %i.",
-        daemon_address, status);
+    ERROR ("rrdcached plugin: Failed to connect to RRDCacheD "
+        "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status);
     return (-1);
   }
 
-  head = NULL;
-  status = rrdc_stats_get (&head);
-  if (status != 0)
+  while (42)
   {
-    ERROR ("rrdcached plugin: rrdc_stats_get failed with status %i.", status);
+    /* The RRD client lib does not provide any means for checking a
+     * connection, hence we'll have to retry upon failed operations. */
+    head = NULL;
+    rrd_clear_error ();
+    status = rrdc_stats_get (&head);
+    if (status == 0)
+      break;
+
+    if (!retried)
+    {
+      retried = 1;
+      if (try_reconnect () == 0)
+        continue;
+      /* else: report the error and fail */
+    }
+
+    ERROR ("rrdcached plugin: rrdc_stats_get failed: %s (status=%i).",
+        rrd_get_error (), status);
     return (-1);
   }
 
@@ -407,6 +444,7 @@ static int rc_write (const data_set_t *ds, const value_list_t *vl,
   char values[512];
   char *values_array[2];
   int status;
+  _Bool retried = 0;
 
   if (daemon_address == NULL)
   {
@@ -463,20 +501,34 @@ static int rc_write (const data_set_t *ds, const value_list_t *vl,
     }
   }
 
+  rrd_clear_error ();
   status = rrdc_connect (daemon_address);
   if (status != 0)
   {
-    ERROR ("rrdcached plugin: rrdc_connect (%s) failed with status %i.",
-        daemon_address, status);
+    ERROR ("rrdcached plugin: Failed to connect to RRDCacheD "
+        "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status);
     return (-1);
   }
 
-  status = rrdc_update (filename, /* values_num = */ 1, (void *) values_array);
-  if (status != 0)
+  while (42)
   {
-    ERROR ("rrdcached plugin: rrdc_update (%s, [%s], 1) failed with "
-        "status %i.",
-        filename, values_array[0], status);
+    /* The RRD client lib does not provide any means for checking a
+     * connection, hence we'll have to retry upon failed operations. */
+    rrd_clear_error ();
+    status = rrdc_update (filename, /* values_num = */ 1, (void *) values_array);
+    if (status == 0)
+      break;
+
+    if (!retried)
+    {
+      retried = 1;
+      if (try_reconnect () == 0)
+        continue;
+      /* else: report the error and fail */
+    }
+
+    ERROR ("rrdcached plugin: rrdc_update (%s, [%s], 1) failed: %s (status=%i)",
+        filename, values_array[0], rrd_get_error (), status);
     return (-1);
   }
 
@@ -489,6 +541,7 @@ static int rc_flush (__attribute__((unused)) cdtime_t timeout, /* {{{ */
 {
   char filename[PATH_MAX + 1];
   int status;
+  _Bool retried = 0;
 
   if (identifier == NULL)
     return (EINVAL);
@@ -498,19 +551,34 @@ static int rc_flush (__attribute__((unused)) cdtime_t timeout, /* {{{ */
   else
     ssnprintf (filename, sizeof (filename), "%s.rrd", identifier);
 
+  rrd_clear_error ();
   status = rrdc_connect (daemon_address);
   if (status != 0)
   {
-    ERROR ("rrdcached plugin: rrdc_connect (%s) failed with status %i.",
-        daemon_address, status);
+    ERROR ("rrdcached plugin: Failed to connect to RRDCacheD "
+        "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status);
     return (-1);
   }
 
-  status = rrdc_flush (filename);
-  if (status != 0)
+  while (42)
   {
-    ERROR ("rrdcached plugin: rrdc_flush (%s) failed with status %i.",
-        filename, status);
+    /* The RRD client lib does not provide any means for checking a
+     * connection, hence we'll have to retry upon failed operations. */
+    rrd_clear_error ();
+    status = rrdc_flush (filename);
+    if (status == 0)
+      break;
+
+    if (!retried)
+    {
+      retried = 1;
+      if (try_reconnect () == 0)
+        continue;
+      /* else: report the error and fail */
+    }
+
+    ERROR ("rrdcached plugin: rrdc_flush (%s) failed: %s (status=%i).",
+        filename, rrd_get_error (), status);
     return (-1);
   }
   DEBUG ("rrdcached plugin: rrdc_flush (%s): Success.", filename);
index b8cd0b8..0247387 100644 (file)
@@ -534,7 +534,7 @@ static int tcsv_init(void) { /* {{{ */
         else if (ds->ds_num != 1)
         {
             ERROR ("tail_csv plugin: The type \"%s\" has %zu data sources. "
-                    "Only types with a single data soure are supported.",
+                    "Only types with a single data source are supported.",
                     ds->type, ds->ds_num);
             continue;
         }
index c6a628e..0e58a97 100644 (file)
@@ -126,15 +126,7 @@ static derive_t vserver_get_sock_bytes(const char *s)
 
 static int vserver_read (void)
 {
-#if NAME_MAX < 1024
-# define DIRENT_BUFFER_SIZE (sizeof (struct dirent) + 1024 + 1)
-#else
-# define DIRENT_BUFFER_SIZE (sizeof (struct dirent) + NAME_MAX + 1)
-#endif
-
-       DIR                     *proc;
-       struct dirent   *dent; /* 42 */
-       char dirent_buffer[DIRENT_BUFFER_SIZE];
+       DIR *proc;
 
        errno = 0;
        proc = opendir (PROCDIR);
@@ -148,6 +140,7 @@ static int vserver_read (void)
 
        while (42)
        {
+               struct dirent *dent;
                int len;
                char file[BUFSIZE];
 
@@ -159,20 +152,20 @@ static int vserver_read (void)
 
                int status;
 
-               status = readdir_r (proc, (struct dirent *) dirent_buffer, &dent);
-               if (status != 0)
+               errno = 0;
+               dent = readdir (proc);
+               if (dent == NULL)
                {
                        char errbuf[4096];
-                       ERROR ("vserver plugin: readdir_r failed: %s",
-                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+
+                       if (errno == 0) /* end of directory */
+                               break;
+
+                       ERROR ("vserver plugin: failed to read directory %s: %s",
+                                       PROCDIR, sstrerror (errno, errbuf, sizeof (errbuf)));
                        closedir (proc);
                        return (-1);
                }
-               else if (dent == NULL)
-               {
-                       /* end of directory */
-                       break;
-               }
 
                if (dent->d_name[0] == '.')
                        continue;
index def3d9c..bafbfe5 100644 (file)
@@ -91,7 +91,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */
     node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout);
     if (node->conn == NULL)
     {
-      ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: Unkown reason",
+      ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: Unknown reason",
           (node->host != NULL) ? node->host : "localhost",
           (node->port != 0) ? node->port : 6379);
       pthread_mutex_unlock (&node->lock);
index 2ef5279..e106d80 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-DEFAULT_VERSION="5.6.0.git"
+DEFAULT_VERSION="5.6.1.git"
 
 if [ -d .git ]; then
        VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"