#include "collectd.h"
-#include "common.h"
#include "plugin.h"
-#include "utils_curl_stats.h"
+#include "utils/common/common.h"
+#include "utils/curl_stats/curl_stats.h"
#include "utils_llist.h"
#include <libxml/parser.h>
char *user;
char *pass;
char *credentials;
- _Bool digest;
- _Bool verify_peer;
- _Bool verify_host;
+ bool digest;
+ bool verify_peer;
+ bool verify_host;
char *cacert;
char *post_body;
int timeout;
while (le != NULL) {
llentry_t *le_next = le->next;
+ /* this also frees xpath->path used for le->key */
cx_xpath_free(le->value);
le = le_next;
}
llist_destroy(list);
-} /* }}} void cx_list_free */
+} /* }}} void cx_xpath_list_free */
static void cx_free(void *arg) /* {{{ */
{
}
if (ds->ds_num != xpath->values_len) {
- WARNING("curl_xml plugin: DataSet `%s' requires %zu values, but config "
- "talks about %zu",
+ WARNING("curl_xml plugin: DataSet `%s' requires %" PRIsz
+ " values, but config talks about %" PRIsz,
xpath->type, ds->ds_num, xpath->values_len);
return -1;
}
return -1;
} /* }}} cx_if_not_text_node */
+/*
+ * Returned value should be freed with xmlFree().
+ */
static char *cx_get_text_node_value(xmlXPathContextPtr xpath_ctx, /* {{{ */
char *expr, const char *from_option) {
xmlXPathObjectPtr values_node_obj = cx_evaluate_xpath(xpath_ctx, expr);
if (tmp_size == 0) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" %sdoesn't match "
+ "relative xpath expression \"%s\" from '%s' doesn't match "
"any of the nodes.",
- expr, (from_option == NULL) ? "" : from_option);
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
return NULL;
}
if (tmp_size > 1) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" %sis expected to return "
+ "relative xpath expression \"%s\" from '%s' is expected to return "
"only one text node. Skipping the node.",
- expr, (from_option == NULL) ? "" : from_option);
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
return NULL;
}
/* ignoring the element if other than textnode/attribute*/
if (cx_if_not_text_node(values_node->nodeTab[0])) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" %sis expected to return "
+ "relative xpath expression \"%s\" from '%s' is expected to return "
"only text/attribute node which is not the case. "
"Skipping the node.",
- expr, (from_option == NULL) ? "" : from_option);
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
return NULL;
}
value_list_t *vl, int index) {
char *node_value = cx_get_text_node_value(
- xpath_ctx, xpath->values[index].path, "from 'ValuesFrom' ");
+ xpath_ctx, xpath->values[index].path, "ValuesFrom");
if (node_value == NULL)
return -1;
/* endptr = */ NULL);
}
- sfree(node_value);
+ xmlFree(node_value);
/* We have reached here which means that
* we have got something to work */
static int cx_handle_instance_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
cx_xpath_t *xpath, value_list_t *vl) {
- memset(vl->type_instance, 0, sizeof(vl->type_instance));
-
/* Handle type instance */
if (xpath->instance != NULL) {
- char *node_value = cx_get_text_node_value(xpath_ctx, xpath->instance,
- "from 'InstanceFrom' ");
+ char *node_value =
+ cx_get_text_node_value(xpath_ctx, xpath->instance, "InstanceFrom");
if (node_value == NULL)
return -1;
else
sstrncpy(vl->type_instance, node_value, sizeof(vl->type_instance));
- sfree(node_value);
+ xmlFree(node_value);
} else if (xpath->instance_prefix != NULL)
sstrncpy(vl->type_instance, xpath->instance_prefix,
sizeof(vl->type_instance));
/* Handle plugin instance */
if (xpath->plugin_instance_from != NULL) {
char *node_value = cx_get_text_node_value(
- xpath_ctx, xpath->plugin_instance_from, "from 'PluginInstanceFrom' ");
+ xpath_ctx, xpath->plugin_instance_from, "PluginInstanceFrom");
if (node_value == NULL)
return -1;
sstrncpy(vl->plugin_instance, node_value, sizeof(vl->plugin_instance));
- sfree(node_value);
+ xmlFree(node_value);
}
return 0;
"since the base xpath expression \"%s\" "
"returned multiple results. Skipping the xpath block...",
xpath->path);
+ xmlXPathFreeObject(base_node_obj);
return -1;
}
return -1;
}
- if (db->xpath_list == NULL) {
- db->xpath_list = llist_create();
- if (db->xpath_list == NULL) {
- ERROR("curl_xml plugin: list creation failed.");
- cx_xpath_free(xpath);
- return -1;
- }
+ if (xpath->values_len == 0) {
+ WARNING("curl_xml plugin: `ValuesFrom' missing in `xpath' block.");
+ cx_xpath_free(xpath);
+ return -1;
}
llentry_t *le = llentry_create(xpath->path, xpath);
static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
{
- int status = 0;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_xml plugin: The `URL' block "
"needs exactly one string argument.");
return -1;
}
- db->timeout = -1;
+ db->instance = strdup("default");
+ if (db->instance == NULL) {
+ ERROR("curl_xml plugin: strdup failed.");
+ sfree(db);
+ return -1;
+ }
- if (strcasecmp("URL", ci->key) == 0) {
- status = cf_util_get_string(ci, &db->url);
- if (status != 0) {
- sfree(db);
- return status;
- }
- } else {
- ERROR("curl_xml plugin: cx_config: "
- "Invalid key: %s",
- ci->key);
- cx_free(db);
+ db->xpath_list = llist_create();
+ if (db->xpath_list == NULL) {
+ ERROR("curl_xml plugin: list creation failed.");
+ sfree(db->instance);
+ sfree(db);
return -1;
}
+ db->timeout = -1;
+
+ int status = cf_util_get_string(ci, &db->url);
+ if (status != 0) {
+ llist_destroy(db->xpath_list);
+ sfree(db->instance);
+ sfree(db);
+ return status;
+ }
+
+ cdtime_t interval = 0;
+
/* Fill the `cx_t' structure.. */
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
status = cf_util_get_string(child, &db->post_body);
else if (strcasecmp("Namespace", child->key) == 0)
status = cx_config_add_namespace(db, child);
+ else if (strcasecmp("Interval", child->key) == 0)
+ status = cf_util_get_cdtime(child, &interval);
else if (strcasecmp("Timeout", child->key) == 0)
status = cf_util_get_int(child, &db->timeout);
else if (strcasecmp("Statistics", child->key) == 0) {
break;
}
- if (status == 0) {
- if (db->xpath_list == NULL) {
- WARNING("curl_xml plugin: No (valid) `xpath' block "
- "within `URL' block `%s'.",
- db->url);
- status = -1;
- }
- if (status == 0)
- status = cx_init_curl(db);
+ if (status != 0) {
+ cx_free(db);
+ return status;
}
- /* If all went well, register this database for reading */
- if (status == 0) {
- if (db->instance == NULL)
- db->instance = strdup("default");
-
- DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
-
- char *cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+ if (llist_size(db->xpath_list) == 0) {
+ WARNING("curl_xml plugin: No `xpath' block within `URL' block `%s'.",
+ db->url);
+ cx_free(db);
+ return -1;
+ }
- plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ 0,
- &(user_data_t){
- .data = db, .free_func = cx_free,
- });
- sfree(cb_name);
- } else {
+ if (cx_init_curl(db) != 0) {
cx_free(db);
return -1;
}
+ /* If all went well, register this database for reading */
+ DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
+
+ char *cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+
+ plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
+ /* interval = */ interval,
+ &(user_data_t){
+ .data = db, .free_func = cx_free,
+ });
+ sfree(cb_name);
return 0;
} /* }}} int cx_config_add_url */