From 3b87d3221e57d8f4d3a442bf1d82ea7ae2180047 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Thu, 19 Feb 2009 10:12:16 +0100 Subject: [PATCH] bind plugin: Fix a counter vs. gauge problem with memory statistics. Thanks to Bruno for the heads-up :) --- src/bind.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/src/bind.c b/src/bind.c index bb3496ca..828a6e80 100644 --- a/src/bind.c +++ b/src/bind.c @@ -59,7 +59,7 @@ * `list_info_ptr_t' are passed to the callbacks in the `void *user_data' * pointer. */ -typedef int (*list_callback_t) (const char *name, counter_t value, +typedef int (*list_callback_t) (const char *name, value_t value, time_t current_time, void *user_data); struct cb_view_s @@ -252,13 +252,13 @@ static void remove_special (char *buffer, size_t buffer_size) /* {{{ */ } } /* }}} void remove_special */ -static void submit_counter(time_t ts, const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, counter_t value) +static void submit (time_t ts, const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, value_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].counter = value; + values[0] = value; vl.values = values; vl.values_len = 1; @@ -277,7 +277,7 @@ static void submit_counter(time_t ts, const char *plugin_instance, /* {{{ */ remove_special (vl.plugin_instance, sizeof (vl.plugin_instance)); } plugin_dispatch_values(&vl); -} /* }}} void submit_counter */ +} /* }}} void submit */ static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ size_t nmemb, void __attribute__((unused)) *stream) @@ -312,7 +312,7 @@ static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ * Callback, that's called with a translation table. * (Plugin instance is fixed, type and type instance come from lookup table.) */ -static int bind_xml_table_callback (const char *name, counter_t value, /* {{{ */ +static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ time_t current_time, void *user_data) { translation_table_ptr_t *table = (translation_table_ptr_t *) user_data; @@ -326,7 +326,7 @@ static int bind_xml_table_callback (const char *name, counter_t value, /* {{{ */ if (strcmp (table->table[i].xml_name, name) != 0) continue; - submit_counter (current_time, + submit (current_time, table->plugin_instance, table->table[i].type, table->table[i].type_instance, @@ -342,14 +342,14 @@ static int bind_xml_table_callback (const char *name, counter_t value, /* {{{ */ * (Plugin instance and type are fixed, xml name is used as type instance.) */ static int bind_xml_list_callback (const char *name, /* {{{ */ - counter_t value, time_t current_time, void *user_data) + value_t value, time_t current_time, void *user_data) { list_info_ptr_t *list_info = (list_info_ptr_t *) user_data; if (list_info == NULL) return (-1); - submit_counter (current_time, + submit (current_time, list_info->plugin_instance, list_info->type, /* type instance = */ name, @@ -389,6 +389,37 @@ static int bind_xml_read_counter (xmlDoc *doc, xmlNode *node, /* {{{ */ return (0); } /* }}} int bind_xml_read_counter */ +static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ + gauge_t *ret_value) +{ + char *str_ptr, *end_ptr; + double value; + + str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) + { + ERROR ("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); + return (-1); + } + + errno = 0; + value = strtod (str_ptr, &end_ptr); + xmlFree(str_ptr); + if (str_ptr == end_ptr || errno) + { + if (errno && (value < 0)) + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); + else if (errno && (value > 0)) + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); + else + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed."); + return (-1); + } + + *ret_value = (gauge_t) value; + return (0); +} /* }}} int bind_xml_read_gauge */ + static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ xmlDoc *doc, xmlXPathContext *xpathCtx, time_t *ret_value) { @@ -459,7 +490,7 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ * Reads statistics in the form: * * QUERY - * 123 + * 123 * */ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ */ @@ -486,10 +517,15 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * { xmlNode *name_node = NULL; xmlNode *counter = NULL; + xmlNode *parent; xmlNode *child; + parent = xpathObj->nodesetval->nodeTab[i]; + DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;", + (char *) parent->name); + /* Iterate over all child nodes. */ - for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; + for (child = parent->xmlChildrenNode; child != NULL; child = child->next) { @@ -506,10 +542,10 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * { char *name = (char *) xmlNodeListGetString (doc, name_node->xmlChildrenNode, 1); - counter_t value; + value_t value; int status; - status = bind_xml_read_counter (doc, counter, &value); + status = bind_xml_read_counter (doc, counter, &value.counter); if (status != 0) continue; @@ -545,7 +581,7 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * list_callback_t list_callback, void *user_data, xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time) + time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; @@ -571,14 +607,18 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * child = child->next) { char *node_name; - counter_t value; + value_t value; int status; if (child->type != XML_ELEMENT_NODE) continue; node_name = (char *) child->name; - status = bind_xml_read_counter (doc, child, &value); + + if (ds_type == DS_TYPE_GAUGE) + status = bind_xml_read_gauge (doc, child, &value.gauge); + else + status = bind_xml_read_counter (doc, child, &value.counter); if (status != 0) continue; @@ -663,7 +703,7 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_value_list (/* xpath = */ "counters", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, path_ctx, current_time); + doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ xmlXPathFreeObject (path_obj); @@ -972,7 +1012,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_value_list ("server/nsstats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { @@ -1018,7 +1058,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_value_list ("server/zonestats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { @@ -1065,7 +1105,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_value_list ("server/resstats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { @@ -1099,7 +1139,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_value_list ("memory/summary", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_GAUGE); } if (views_num > 0) -- 2.11.0