X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrdcached.c;h=6d45ac9fdf5287644edae598a4f2912a03686439;hb=8c5927c52f4eefebaad3a6ecadc253ee9007ebb5;hp=3a6c98516a55772d3c51c543a2dcd1cb4aa10078;hpb=7b64cc91d3307179557b25b6ece2349a088f4294;p=collectd.git diff --git a/src/rrdcached.c b/src/rrdcached.c index 3a6c9851..6d45ac9f 100644 --- a/src/rrdcached.c +++ b/src/rrdcached.c @@ -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; - size_t 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) @@ -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,14 +287,35 @@ 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; + vl.values = &(value_t) { .gauge = NAN }; + vl.values_len = 1; if (daemon_address == NULL) return (-1); @@ -304,38 +323,49 @@ static int rc_read (void) if (!config_collect_stats) return (-1); - vl.values = values; - vl.values_len = 1; - - if ((strncmp ("unix:", daemon_address, strlen ("unix:")) == 0) - || (daemon_address[0] == '/')) - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - else + if ((strncmp ("unix:", daemon_address, strlen ("unix:")) != 0) + && (daemon_address[0] != '/')) 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; + vl.values[0].gauge = (gauge_t) ptr->value.gauge; else if (ptr->type == RRDC_STATS_TYPE_COUNTER) - values[0].counter = (counter_t) ptr->value.counter; + vl.values[0].counter = (counter_t) ptr->value.counter; else continue; @@ -414,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) { @@ -470,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); } @@ -496,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); @@ -505,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);