From de067db48b0f16b6678a900339801c6cb59681a3 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sun, 19 Oct 2014 20:25:50 +0200 Subject: [PATCH] Use the complain mechanism to report write failures. This ensures that we don't spam the log for each submitted value. Instead, an exponential backup is used to report permanent errors starting at one message per second. --- src/filter_chain.c | 67 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/src/filter_chain.c b/src/filter_chain.c index 7d8369b9..5ad9655c 100644 --- a/src/filter_chain.c +++ b/src/filter_chain.c @@ -73,6 +73,15 @@ struct fc_chain_s /* {{{ */ fc_chain_t *next; }; /* }}} */ +/* Writer configuration. */ +struct fc_writer_s; +typedef struct fc_writer_s fc_writer_t; /* {{{ */ +struct fc_writer_s +{ + char *plugin; + c_complain_t complaint; +}; /* }}} */ + /* * Global variables */ @@ -609,16 +618,13 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ { int i; - char **plugin_list; - size_t plugin_list_len; - - plugin_list = NULL; - plugin_list_len = 0; + fc_writer_t *plugin_list = NULL; + size_t plugin_list_len = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - char **temp; + fc_writer_t *temp; int j; if (strcasecmp ("Plugin", child->key) != 0) @@ -631,14 +637,17 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ for (j = 0; j < child->values_num; j++) { + char *plugin; + if (child->values[j].type != OCONFIG_TYPE_STRING) { ERROR ("Filter subsystem: Built-in target `write': " "The `Plugin' option accepts only string arguments."); continue; } + plugin = child->values[j].value.string; - temp = (char **) realloc (plugin_list, (plugin_list_len + 2) + temp = (fc_writer_t *) realloc (plugin_list, (plugin_list_len + 2) * (sizeof (*plugin_list))); if (temp == NULL) { @@ -647,14 +656,15 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ } plugin_list = temp; - plugin_list[plugin_list_len] = fc_strdup (child->values[j].value.string); - if (plugin_list[plugin_list_len] == NULL) + plugin_list[plugin_list_len].plugin = fc_strdup (plugin); + if (plugin_list[plugin_list_len].plugin == NULL) { ERROR ("fc_bit_write_create: fc_strdup failed."); continue; } + C_COMPLAIN_INIT (&plugin_list[plugin_list_len].complaint); plugin_list_len++; - plugin_list[plugin_list_len] = NULL; + plugin_list[plugin_list_len].plugin = NULL; } /* for (j = 0; j < child->values_num; j++) */ } /* for (i = 0; i < ci->children_num; i++) */ @@ -665,7 +675,7 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ static int fc_bit_write_destroy (void **user_data) /* {{{ */ { - char **plugin_list; + fc_writer_t *plugin_list; size_t i; if ((user_data == NULL) || (*user_data == NULL)) @@ -673,8 +683,8 @@ static int fc_bit_write_destroy (void **user_data) /* {{{ */ plugin_list = *user_data; - for (i = 0; plugin_list[i] != NULL; i++) - free (plugin_list[i]); + for (i = 0; plugin_list[i].plugin != NULL; i++) + free (plugin_list[i].plugin); free (plugin_list); return (0); @@ -684,23 +694,23 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { - char **plugin_list; + fc_writer_t *plugin_list; int status; plugin_list = NULL; if (user_data != NULL) plugin_list = *user_data; - if ((plugin_list == NULL) || (plugin_list[0] == NULL)) + if ((plugin_list == NULL) || (plugin_list[0].plugin == NULL)) { - static c_complain_t enoent_complaint = C_COMPLAIN_INIT_STATIC; + static c_complain_t write_complaint = C_COMPLAIN_INIT_STATIC; status = plugin_write (/* plugin = */ NULL, ds, vl); if (status == ENOENT) { /* in most cases this is a permanent error, so use the complain * mechanism rather than spamming the logs */ - c_complain (LOG_INFO, &enoent_complaint, + c_complain (LOG_INFO, &write_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.", @@ -708,13 +718,16 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ } else if (status != 0) { - INFO ("Filter subsystem: Built-in target `write': Dispatching value to " + /* often, this is a permanent error (e.g. target system unavailable), + * so use the complain mechanism rather than spamming the logs */ + c_complain (LOG_INFO, &write_complaint, + "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: " + c_release (LOG_INFO, &write_complaint, "Filter subsystem: " "Built-in target `write': Some write plugin is back to normal " "operation. `write' succeeded."); } @@ -723,13 +736,21 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ { size_t i; - for (i = 0; plugin_list[i] != NULL; i++) + for (i = 0; plugin_list[i].plugin != NULL; i++) { - status = plugin_write (plugin_list[i], ds, vl); + status = plugin_write (plugin_list[i].plugin, ds, vl); if (status != 0) { - INFO ("Filter subsystem: Built-in target `write': Dispatching value to " - "the `%s' plugin failed with status %i.", plugin_list[i], status); + c_complain (LOG_INFO, &plugin_list[i].complaint, + "Filter subsystem: Built-in target `write': Dispatching value to " + "the `%s' plugin failed with status %i.", + plugin_list[i].plugin, status); + } + else + { + c_release (LOG_INFO, &plugin_list[i].complaint, + "Filter subsystem: Built-in target `write': Plugin `%s' is back " + "to normal operation. `write' succeeded.", plugin_list[i].plugin); } } /* for (i = 0; plugin_list[i] != NULL; i++) */ } -- 2.11.0