X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fbind.c;h=c5327f14b8aaeed5ad687705e6b14e69ca0b675e;hb=f701e685eab83f37ecc6501d7dbe4eb941a454bb;hp=6a6ec747b50da8d9d1219cfc4e0dbc3ee819920d;hpb=78e89b2e0c205c7d22ade735e3987fba42407206;p=collectd.git diff --git a/src/bind.c b/src/bind.c index 6a6ec747..c5327f14 100644 --- a/src/bind.c +++ b/src/bind.c @@ -109,6 +109,7 @@ static int global_server_stats = 1; static int global_zone_maint_stats = 1; static int global_resolver_stats = 0; static int global_memory_stats = 1; +static int timeout = -1; static cb_view_t *views = NULL; static size_t views_num = 0; @@ -266,7 +267,7 @@ static void submit (time_t ts, const char *plugin_instance, /* {{{ */ if (type_instance) { sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + replace_special (vl.type_instance, sizeof (vl.type_instance)); } plugin_dispatch_values(&vl); } /* }}} void submit */ @@ -369,9 +370,11 @@ static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ { ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.", str_ptr); + xmlFree(str_ptr); return (-1); } + xmlFree(str_ptr); *ret_value = value.derive; return (0); } /* }}} int bind_xml_read_derive */ @@ -670,29 +673,29 @@ static int bind_parse_generic_name_attr_value_list (const char *xpath_expression if (child->type != XML_ELEMENT_NODE) continue; - if (strncmp ("counter", (char *) child->name, strlen ("counter")) == 0) + if (strncmp ("counter", (char *) child->name, strlen ("counter")) != 0) + continue; + + char *attr_name; + value_t value; + int status; + + attr_name = (char *) xmlGetProp (child, BAD_CAST "name"); + if (attr_name == NULL) { - char *attr_name; - value_t value; - int status; - - attr_name = (char *) xmlGetProp (child, BAD_CAST "name"); - if (attr_name == NULL) - { - DEBUG ("bind plugin: found without name."); - continue; - } - 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; - - status = (*list_callback) (attr_name, value, current_time, user_data); - if (status == 0) - num_entries++; + DEBUG ("bind plugin: found without name."); + continue; } + 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; + + status = (*list_callback) (attr_name, value, current_time, user_data); + if (status == 0) + num_entries++; } } @@ -714,25 +717,40 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ int i; size_t j; - path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); - if (path_obj == NULL) + if (version >= 3) { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); - return (-1); + char *n = (char *) xmlGetProp (node, BAD_CAST "name"); + char *c = (char *) xmlGetProp (node, BAD_CAST "rdataclass"); + if (n && c) + { + zone_name = (char *) xmlMalloc(strlen(n) + strlen(c) + 2); + snprintf(zone_name, strlen(n) + strlen(c) + 2, "%s/%s", n, c); + } + xmlFree(n); + xmlFree(c); } - - for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) + else { - zone_name = (char *) xmlNodeListGetString (doc, - path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); - if (zone_name != NULL) - break; + path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); + if (path_obj == NULL) + { + ERROR ("bind plugin: xmlXPathEvalExpression failed."); + return (-1); + } + + for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) + { + zone_name = (char *) xmlNodeListGetString (doc, + path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); + if (zone_name != NULL) + break; + } + xmlXPathFreeObject (path_obj); } if (zone_name == NULL) { ERROR ("bind plugin: Could not determine zone name."); - xmlXPathFreeObject (path_obj); return (-1); } @@ -745,11 +763,8 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ xmlFree (zone_name); zone_name = NULL; - if (j >= views_num) - { - xmlXPathFreeObject (path_obj); + if (j >= view->zones_num) return (0); - } zone_name = view->zones[j]; @@ -768,14 +783,31 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-zone-%s", view->name, zone_name); - bind_parse_generic_value_list (/* xpath = */ "counters", + if (version == 3) + { + list_info_ptr_t list_info = + { + plugin_instance, + /* type = */ "dns_qtype" + }; + bind_parse_generic_name_attr_value_list (/* xpath = */ "counters[@type='rcode']", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, path_ctx, current_time, DS_TYPE_COUNTER); + bind_parse_generic_name_attr_value_list (/* xpath = */ "counters[@type='qtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, + doc, path_ctx, current_time, DS_TYPE_COUNTER); + } + else + { + bind_parse_generic_value_list (/* xpath = */ "counters", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, + doc, path_ctx, current_time, DS_TYPE_COUNTER); + } } /* }}} */ - xmlXPathFreeObject (path_obj); - return (0); } /* }}} int bind_xml_stats_handle_zone */ @@ -968,8 +1000,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ doc, path_ctx, current_time, DS_TYPE_GAUGE); } /* }}} */ - // v3 does not provide per-zone stats any more - if (version < 3 && view->zones_num > 0) + if (view->zones_num > 0) bind_xml_stats_search_zones (version, doc, path_ctx, node, view, current_time); @@ -1016,24 +1047,142 @@ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ return (0); } /* }}} int bind_xml_stats_search_views */ -static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode) +static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) { - time_t current_time = 0; - int status; + /* XPath: server/counters[@type='opcode'] + * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... + * Layout v3: + * + * 1 + * : + * + */ + if (global_opcodes != 0) + { + list_info_ptr_t list_info = + { + /* plugin instance = */ "global-opcodes", + /* type = */ "dns_opcode" + }; + bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='opcode']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); + } - xpathCtx->node = statsnode; + /* XPath: server/counters[@type='qtype'] + * Variables: RESERVED0, A, NS, CNAME, SOA, MR, PTR, HINFO, MX, TXT, RP, + * X25, PX, AAAA, LOC, SRV, NAPTR, A6, DS, RRSIG, NSEC, DNSKEY, + * SPF, TKEY, IXFR, AXFR, ANY, ..., Others + * Layout v3: + * + * 1 + * : + * + */ + if (global_qtypes != 0) + { + list_info_ptr_t list_info = + { + /* plugin instance = */ "global-qtypes", + /* type = */ "dns_qtype" + }; - /* TODO: Check `server/boot-time' to recognize server restarts. */ + bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='qtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); + } - status = bind_xml_read_timestamp ("server/current-time", - doc, xpathCtx, ¤t_time); - if (status != 0) + /* XPath: server/counters[@type='nsstat'] + * Variables: Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, + * ReqSIG0, ReqBadSIG, ReqTCP, AuthQryRej, RecQryRej, XfrRej, + * UpdateRej, Response, TruncatedResp, RespEDNS0, RespTSIG, + * RespSIG0, QrySuccess, QryAuthAns, QryNoauthAns, QryReferral, + * QryNxrrset, QrySERVFAIL, QryFORMERR, QryNXDOMAIN, QryRecursion, + * QryDuplicate, QryDropped, QryFailure, XfrReqDone, UpdateReqFwd, + * UpdateRespFwd, UpdateFwdFail, UpdateDone, UpdateFail, + * UpdateBadPrereq + * Layout v3: + * 1 + * 0 + * : + * + */ + if (global_server_stats) { - ERROR ("bind plugin: Reading `server/current-time' failed."); - return (-1); + translation_table_ptr_t table_ptr = + { + nsstats_translation_table, + nsstats_translation_table_length, + /* plugin_instance = */ "global-server_stats" + }; + + bind_parse_generic_name_attr_value_list ("server/counters[@type='nsstat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - DEBUG ("bind plugin: Current server time is %i.", (int) current_time); + + /* XPath: server/zonestats, server/zonestat, server/counters[@type='zonestat'] + * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, + * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, + * XfrSuccess, XfrFail + * Layout v3: + * 0 + * 0 + * : + * + */ + if (global_zone_maint_stats) + { + translation_table_ptr_t table_ptr = + { + zonestats_translation_table, + zonestats_translation_table_length, + /* plugin_instance = */ "global-zone_maint_stats" + }; + + bind_parse_generic_name_attr_value_list ("server/counters[@type='zonestat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); + } + + /* XPath: server/resstats, server/counters[@type='resstat'] + * Variables: Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, + * FORMERR, OtherError, EDNS0Fail, Mismatch, Truncated, Lame, + * Retry, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, + * GlueFetchv6Fail, ValAttempt, ValOk, ValNegOk, ValFail + * Layout v3: + * 0 + * 0 + * : + * + */ + if (global_resolver_stats != 0) + { + translation_table_ptr_t table_ptr = + { + resstats_translation_table, + resstats_translation_table_length, + /* plugin_instance = */ "global-resolver_stats" + }; + + bind_parse_generic_name_attr_value_list ("server/counters[@type='resstat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); + } +} /* }}} bind_xml_stats_v3 */ + +static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) +{ /* XPath: server/requests/opcode, server/counters[@type='opcode'] * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... * Layout V1 and V2: @@ -1042,12 +1191,6 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 1 * * : - * - * Layout v3: - * - * 1 - * : - * */ if (global_opcodes != 0) { @@ -1056,20 +1199,11 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* plugin instance = */ "global-opcodes", /* type = */ "dns_opcode" }; - if (version == 3) - { - bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='opcode']", + + bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } } /* XPath: server/queries-in/rdtype, server/counters[@type='qtype'] @@ -1082,12 +1216,6 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 1 * * : - * - * Layout v3: - * - * 1 - * : - * */ if (global_qtypes != 0) { @@ -1096,20 +1224,11 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* plugin instance = */ "global-qtypes", /* type = */ "dns_qtype" }; - if (version == 3) - { - bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='qtype']", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } + + bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, + doc, xpathCtx, current_time, DS_TYPE_COUNTER); } /* XPath: server/nsstats, server/nsstat, server/counters[@type='nsstat'] @@ -1137,17 +1256,11 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 0 * * : - * Layout v3: - * 1 - * 0 - * : - * */ if (global_server_stats) { translation_table_ptr_t table_ptr = - { + { nsstats_translation_table, nsstats_translation_table_length, /* plugin_instance = */ "global-server_stats" @@ -1160,20 +1273,13 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - else if (version == 2) + else { bind_parse_generic_name_value ("server/nsstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - else // version == 3 - { - bind_parse_generic_name_attr_value_list ("server/counters[@type='nsstat']", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } } /* XPath: server/zonestats, server/zonestat, server/counters[@type='zonestat'] @@ -1196,17 +1302,11 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 0 * * : - * Layout v3: - * 0 - * 0 - * : - * */ if (global_zone_maint_stats) { translation_table_ptr_t table_ptr = - { + { zonestats_translation_table, zonestats_translation_table_length, /* plugin_instance = */ "global-zone_maint_stats" @@ -1219,20 +1319,13 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - else if (version == 2) + else { bind_parse_generic_name_value ("server/zonestat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - else // version == 3 - { - bind_parse_generic_name_attr_value_list ("server/counters[@type='zonestat']", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } } /* XPath: server/resstats, server/counters[@type='resstat'] @@ -1256,17 +1349,11 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 0 * * : - * Layout v3: - * 0 - * 0 - * : - * */ if (global_resolver_stats != 0) { translation_table_ptr_t table_ptr = - { + { resstats_translation_table, resstats_translation_table_length, /* plugin_instance = */ "global-resolver_stats" @@ -1279,21 +1366,43 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } - else if (version == 2) - { - bind_parse_generic_name_value ("server/resstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } else { - bind_parse_generic_name_attr_value_list ("server/counters[@type='resstat']", + bind_parse_generic_name_value ("server/resstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } +} /* }}} bind_xml_stats_v1_v2 */ + +static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode) +{ + time_t current_time = 0; + int status; + + xpathCtx->node = statsnode; + + /* TODO: Check `server/boot-time' to recognize server restarts. */ + + status = bind_xml_read_timestamp ("server/current-time", + doc, xpathCtx, ¤t_time); + if (status != 0) + { + ERROR ("bind plugin: Reading `server/current-time' failed."); + return (-1); + } + DEBUG ("bind plugin: Current server time is %i.", (int) current_time); + + if (version == 3) + { + bind_xml_stats_v3(doc, xpathCtx, statsnode, current_time); + } + else + { + bind_xml_stats_v1_v2(version, doc, xpathCtx, statsnode, current_time); + } /* XPath: memory/summary * Variables: TotalUse, InUse, BlockSize, ContextSize, Lost @@ -1557,7 +1666,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ if (tmp->name == NULL) { ERROR ("bind plugin: strdup failed."); - free (tmp); + sfree (views); return (-1); } @@ -1617,6 +1726,8 @@ static int bind_config (oconfig_item_t *ci) /* {{{ */ bind_config_add_view (child); else if (strcasecmp ("ParseTime", child->key) == 0) cf_util_get_boolean (child, &config_parse_time); + else if (strcasecmp ("Timeout", child->key) == 0) + cf_util_get_int (child, &timeout); else { WARNING ("bind plugin: Unknown configuration option " @@ -1646,6 +1757,11 @@ static int bind_init (void) /* {{{ */ curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); +#ifdef HAVE_CURLOPT_TIMEOUT_MS + curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (timeout >= 0) ? + (long) timeout : CDTIME_T_TO_MS(plugin_get_interval())); +#endif + return (0); } /* }}} int bind_init */