collectd-tg: Fix sleep interval.
[collectd.git] / src / rrdcached.c
index 645032c..0b90405 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_rrdcreate.h"
@@ -69,7 +70,6 @@ static int value_list_to_string (char *buffer, int buffer_len,
 {
   int offset;
   int status;
-  int i;
   time_t t;
 
   assert (0 == strcmp (ds->type, vl->type));
@@ -82,7 +82,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
     return (-1);
   offset = status;
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if ((ds->ds[i].type != DS_TYPE_COUNTER)
         && (ds->ds[i].type != DS_TYPE_GAUGE)
@@ -95,7 +95,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
       status = ssnprintf (buffer + offset, buffer_len - offset,
           ":%llu", vl->values[i].counter);
     }
-    else if (ds->ds[i].type == DS_TYPE_GAUGE) 
+    else if (ds->ds[i].type == DS_TYPE_GAUGE)
     {
       status = ssnprintf (buffer + offset, buffer_len - offset,
           ":%f", vl->values[i].gauge);
@@ -107,7 +107,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
     else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ {
       status = ssnprintf (buffer + offset, buffer_len - offset,
          ":%"PRIu64, vl->values[i].absolute);
+
     }
 
     if ((status < 1) || (status >= (buffer_len - offset)))
@@ -217,9 +217,7 @@ static int rc_config_add_timespan (int timespan)
 
 static int rc_config (oconfig_item_t *ci)
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t const *child = ci->children + i;
     const char *key = child->key;
@@ -289,11 +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;
-  rrdc_stats_t *ptr;
+  _Bool retried = 0;
 
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
@@ -314,23 +332,39 @@ 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);
   }
 
-  for (ptr = head; ptr != NULL; ptr = ptr->next)
+  for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next)
   {
     if (ptr->type == RRDC_STATS_TYPE_GAUGE)
       values[0].gauge = (gauge_t) ptr->value.gauge;
@@ -414,6 +448,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)
   {
@@ -470,20 +505,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);
   }
 
@@ -496,6 +545,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);
@@ -505,19 +555,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);