X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fbind.c;h=38d4a27f1ca29de115fe59dd6e119f5414e3914a;hp=bb3496ca464a031c6408885375145d0d597b6be3;hb=59c7ee1cafaf53814838794908dd84f8101334c7;hpb=67fde1b848831de9da2f7a77ab60887ba2b252db diff --git a/src/bind.c b/src/bind.c index bb3496ca..38d4a27f 100644 --- a/src/bind.c +++ b/src/bind.c @@ -1,7 +1,7 @@ /** * collectd - src/bind.c - * Copyright (C) 2009 Bruno Prémont - * Copyright (C) 2009 Florian Forster + * Copyright (C) 2009 Bruno Prémont + * Copyright (C) 2009,2010 Florian Forster * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,34 +18,34 @@ * * Authors: * Bruno Prémont - * Florian Forster + * Florian Forster **/ -/* Set to C99 and POSIX code */ -#ifndef _ISOC99_SOURCE -# define _ISOC99_SOURCE -#endif -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L -#endif -#ifndef _REENTRANT -# define _REENTRANT -#endif -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 600 -#endif -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#endif +#include "config.h" + +#if STRPTIME_NEEDS_STANDARDS +# ifndef _ISOC99_SOURCE +# define _ISOC99_SOURCE 1 +# endif +# ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200112L +# endif +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif +#endif /* STRPTIME_NEEDS_STANDARDS */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" +/* Some versions of libcurl don't include this themselves and then don't have + * fd_set available. */ +#if HAVE_SYS_SELECT_H +# include +#endif + #include #include #include @@ -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 @@ -131,7 +131,7 @@ static const translation_info_t nsstats_translation_table[] = /* {{{ */ /* Rejects */ { "AuthQryRej", "dns_reject", "authorative" }, { "RecQryRej", "dns_reject", "recursive" }, - { "XfrRej", "dns_reject", "transer" }, + { "XfrRej", "dns_reject", "transfer" }, { "UpdateRej", "dns_reject", "update" }, /* Responses */ { "Response", "dns_response", "normal" }, @@ -239,45 +239,32 @@ static int memsummary_translation_table_length = STATIC_ARRAY_SIZE (memsummary_translation_table); /* }}} */ -static void remove_special (char *buffer, size_t buffer_size) /* {{{ */ -{ - size_t i; - - for (i = 0; i < buffer_size; i++) - { - if (buffer[i] == 0) - return; - if ((!isalnum ((int) buffer[i])) && (buffer[i] != '-')) - buffer[i] = '_'; - } -} /* }}} 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; - vl.time = ts; + vl.time = TIME_T_TO_CDTIME_T (ts); sstrncpy(vl.host, hostname_g, sizeof(vl.host)); sstrncpy(vl.plugin, "bind", sizeof(vl.plugin)); if (plugin_instance) { sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - remove_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); } sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance) { sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - remove_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + replace_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 +299,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 +313,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 +329,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, @@ -358,36 +345,62 @@ static int bind_xml_list_callback (const char *name, /* {{{ */ return (0); } /* }}} int bind_xml_list_callback */ -static int bind_xml_read_counter (xmlDoc *doc, xmlNode *node, /* {{{ */ - counter_t *ret_value) +static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ + derive_t *ret_value) +{ + char *str_ptr; + value_t value; + int status; + + str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) + { + ERROR ("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); + return (-1); + } + + status = parse_value (str_ptr, &value, DS_TYPE_DERIVE); + if (status != 0) + { + ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.", + str_ptr); + return (-1); + } + + *ret_value = value.derive; + return (0); +} /* }}} int bind_xml_read_derive */ + +static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ + gauge_t *ret_value) { char *str_ptr, *end_ptr; - long long int value; + double value; str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (str_ptr == NULL) { - ERROR ("bind plugin: bind_xml_read_counter: xmlNodeListGetString failed."); + ERROR ("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); return (-1); } errno = 0; - value = strtoll (str_ptr, &end_ptr, 10); + 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_counter: strtoll failed with underflow."); + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); else if (errno && (value > 0)) - ERROR ("bind plugin: bind_xml_read_counter: strtoll failed with overflow."); + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); else - ERROR ("bind plugin: bind_xml_read_counter: strtoll failed."); + ERROR ("bind plugin: bind_xml_read_gauge: strtod failed."); return (-1); } - *ret_value = value; + *ret_value = (gauge_t) value; return (0); -} /* }}} int bind_xml_read_counter */ +} /* }}} int bind_xml_read_gauge */ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ xmlDoc *doc, xmlXPathContext *xpathCtx, time_t *ret_value) @@ -447,7 +460,7 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ return (-1); } - *ret_value = timegm(&tm); + *ret_value = mktime(&tm); xmlXPathFreeObject (xpathObj); return (0); @@ -459,14 +472,14 @@ 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, /* {{{ */ 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; @@ -486,10 +499,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 +524,13 @@ 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); + if (ds_type == DS_TYPE_GAUGE) + status = bind_xml_read_gauge (doc, counter, &value.gauge); + else + status = bind_xml_read_derive (doc, counter, &value.derive); if (status != 0) continue; @@ -545,7 +566,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 +592,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_derive (doc, child, &value.derive); if (status != 0) continue; @@ -663,7 +688,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); @@ -778,7 +803,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_name_value (/* xpath = */ "rdtype", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, - doc, path_ctx, current_time); + doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ if (view->resolver_stats != 0) /* {{{ */ @@ -797,16 +822,17 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_name_value ("resstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, path_ctx, current_time); + doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ + /* Record types in the cache */ if (view->cacherrsets != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; list_info_ptr_t list_info = { plugin_instance, - /* type = */ "dns_qtype" + /* type = */ "dns_qtype_cached" }; ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets", @@ -815,7 +841,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_name_value (/* xpath = */ "cache/rrset", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, - doc, path_ctx, current_time); + doc, path_ctx, current_time, DS_TYPE_GAUGE); } /* }}} */ if (view->zones_num > 0) @@ -904,7 +930,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } /* XPath: server/queries-in/rdtype @@ -929,7 +955,7 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } /* XPath: server/nsstats, server/nsstat @@ -972,14 +998,14 @@ 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 { bind_parse_generic_name_value ("server/nsstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } @@ -1018,14 +1044,14 @@ 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 { bind_parse_generic_name_value ("server/zonestat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } @@ -1065,14 +1091,14 @@ 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 { bind_parse_generic_name_value ("server/resstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, - doc, xpathCtx, current_time); + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } @@ -1099,7 +1125,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) @@ -1360,10 +1386,12 @@ static int bind_init (void) /* {{{ */ return (-1); } + curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, bind_curl_error); curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); + curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); return (0); } /* }}} int bind_init */