X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Futils_format_kairosdb.c;h=4003243bf79f5661ad580649ab5b5421ee941602;hp=41055c7b336ded0e9580f2982ba607e9be64e673;hb=06a86a60a7dabc685bdbd81ce3d36ea5f7e2c2d4;hpb=9c962b99a3acd77f1d6e2499052b47356819511a diff --git a/src/utils_format_kairosdb.c b/src/utils_format_kairosdb.c index 41055c7b..4003243b 100644 --- a/src/utils_format_kairosdb.c +++ b/src/utils_format_kairosdb.c @@ -24,16 +24,14 @@ * Aurelien beorn Rougemont **/ - #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_cache.h" #include "utils_format_kairosdb.h" - /* This is the KAIROSDB format for write_http output * * Target format @@ -56,264 +54,246 @@ * ] */ -static int kairosdb_escape_string (char *buffer, size_t buffer_size, /* {{{ */ - const char *string) -{ +static int kairosdb_escape_string(char *buffer, size_t buffer_size, /* {{{ */ + const char *string) { size_t dst_pos; if ((buffer == NULL) || (string == NULL)) - return (-EINVAL); + return -EINVAL; if (buffer_size < 3) - return (-ENOMEM); + return -ENOMEM; dst_pos = 0; -#define BUFFER_ADD(c) do { \ - if (dst_pos >= (buffer_size - 1)) { \ - buffer[buffer_size - 1] = 0; \ - return (-ENOMEM); \ - } \ - buffer[dst_pos] = (c); \ - dst_pos++; \ -} while (0) +#define BUFFER_ADD(c) \ + do { \ + if (dst_pos >= (buffer_size - 1)) { \ + buffer[buffer_size - 1] = 0; \ + return -ENOMEM; \ + } \ + buffer[dst_pos] = (c); \ + dst_pos++; \ + } while (0) /* Escape special characters */ /* authorize -_. and alpha num but also escapes " */ - BUFFER_ADD ('"'); - for (size_t src_pos = 0; string[src_pos] != 0; src_pos++) - { - if (isalnum(string[src_pos]) || - 0x2d == string[src_pos] || - 0x2e == string[src_pos] || - 0x5f == string[src_pos]) - BUFFER_ADD (tolower(string[src_pos])); + BUFFER_ADD('"'); + for (size_t src_pos = 0; string[src_pos] != 0; src_pos++) { + if (isalnum(string[src_pos]) || 0x2d == string[src_pos] || + 0x2e == string[src_pos] || 0x5f == string[src_pos]) + BUFFER_ADD(tolower(string[src_pos])); } /* for */ - BUFFER_ADD ('"'); + BUFFER_ADD('"'); buffer[dst_pos] = 0; #undef BUFFER_ADD - return (0); + return 0; } /* }}} int kairosdb_escape_string */ -static int values_to_kairosdb (char *buffer, size_t buffer_size, /* {{{ */ - const data_set_t *ds, const value_list_t *vl, int store_rates, - size_t ds_idx) -{ +static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ + const data_set_t *ds, const value_list_t *vl, + int store_rates, size_t ds_idx) { size_t offset = 0; gauge_t *rates = NULL; - memset (buffer, 0, buffer_size); - -#define BUFFER_ADD(...) do { \ - int status; \ - status = ssnprintf (buffer + offset, buffer_size - offset, \ - __VA_ARGS__); \ - if (status < 1) \ - { \ - sfree(rates); \ - return (-1); \ - } \ - else if (((size_t) status) >= (buffer_size - offset)) \ - { \ - sfree(rates); \ - return (-ENOMEM); \ - } \ - else \ - offset += ((size_t) status); \ -} while (0) - - if (ds->ds[ds_idx].type == DS_TYPE_GAUGE) - { - if (isfinite (vl->values[ds_idx].gauge)) - { - BUFFER_ADD ("[["); - BUFFER_ADD ("%"PRIu64, CDTIME_T_TO_MS (vl->time)); - BUFFER_ADD (","); - BUFFER_ADD (JSON_GAUGE_FORMAT, vl->values[ds_idx].gauge); - } - else - { - DEBUG ("utils_format_kairosdb: invalid vl->values[ds_idx].gauge for %s|%s|%s|%s|%s", - vl->plugin, - vl->plugin_instance, - vl->type, - vl->type_instance, - ds->ds[ds_idx].name); - return (-1); + memset(buffer, 0, buffer_size); + +#define BUFFER_ADD(...) \ + do { \ + int status; \ + status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \ + if (status < 1) { \ + sfree(rates); \ + return -1; \ + } else if (((size_t)status) >= (buffer_size - offset)) { \ + sfree(rates); \ + return -ENOMEM; \ + } else \ + offset += ((size_t)status); \ + } while (0) + + if (ds->ds[ds_idx].type == DS_TYPE_GAUGE) { + if (isfinite(vl->values[ds_idx].gauge)) { + BUFFER_ADD("[["); + BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); + BUFFER_ADD(","); + BUFFER_ADD(JSON_GAUGE_FORMAT, vl->values[ds_idx].gauge); + } else { + DEBUG("utils_format_kairosdb: invalid vl->values[ds_idx].gauge for " + "%s|%s|%s|%s|%s", + vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, + ds->ds[ds_idx].name); + return -1; } - } - else if (store_rates) - { - if (rates == NULL) - rates = uc_get_rate (ds, vl); + } else if (store_rates) { if (rates == NULL) - { - WARNING ("utils_format_kairosdb: uc_get_rate failed for %s|%s|%s|%s|%s", - vl->plugin, - vl->plugin_instance, - vl->type, - vl->type_instance, - ds->ds[ds_idx].name); - - return (-1); - } + rates = uc_get_rate(ds, vl); + if (rates == NULL) { + WARNING("utils_format_kairosdb: uc_get_rate failed for %s|%s|%s|%s|%s", + vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, + ds->ds[ds_idx].name); - if (isfinite (rates[ds_idx])) - { - BUFFER_ADD ("[["); - BUFFER_ADD ("%"PRIu64, CDTIME_T_TO_MS (vl->time)); - BUFFER_ADD (","); - BUFFER_ADD (JSON_GAUGE_FORMAT, rates[ds_idx]); + return -1; } - else - { - WARNING ("utils_format_kairosdb: invalid rates[ds_idx] for %s|%s|%s|%s|%s", - vl->plugin, - vl->plugin_instance, - vl->type, - vl->type_instance, - ds->ds[ds_idx].name); + + if (isfinite(rates[ds_idx])) { + BUFFER_ADD("[["); + BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); + BUFFER_ADD(","); + BUFFER_ADD(JSON_GAUGE_FORMAT, rates[ds_idx]); + } else { + WARNING("utils_format_kairosdb: invalid rates[ds_idx] for %s|%s|%s|%s|%s", + vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, + ds->ds[ds_idx].name); sfree(rates); - return (-1); + return -1; } + } else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) { + BUFFER_ADD("[["); + BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); + BUFFER_ADD(","); + BUFFER_ADD("%" PRIu64, (uint64_t)vl->values[ds_idx].counter); + } else if (ds->ds[ds_idx].type == DS_TYPE_DERIVE) { + BUFFER_ADD("[["); + BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); + BUFFER_ADD(","); + BUFFER_ADD("%" PRIi64, vl->values[ds_idx].derive); + } else if (ds->ds[ds_idx].type == DS_TYPE_ABSOLUTE) { + BUFFER_ADD("[["); + BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time)); + BUFFER_ADD(","); + BUFFER_ADD("%" PRIu64, vl->values[ds_idx].absolute); + } else { + ERROR("format_kairosdb: Unknown data source type: %i", ds->ds[ds_idx].type); + sfree(rates); + return -1; } - else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) - { - BUFFER_ADD ("[["); - BUFFER_ADD ("%"PRIu64, CDTIME_T_TO_MS (vl->time)); - BUFFER_ADD (","); - BUFFER_ADD ("%llu", vl->values[ds_idx].counter); - } - else if (ds->ds[ds_idx].type == DS_TYPE_DERIVE) - { - BUFFER_ADD ("[["); - BUFFER_ADD ("%"PRIu64, CDTIME_T_TO_MS (vl->time)); - BUFFER_ADD (","); - BUFFER_ADD ("%"PRIi64, vl->values[ds_idx].derive); - } - else if (ds->ds[ds_idx].type == DS_TYPE_ABSOLUTE) - { - BUFFER_ADD ("[["); - BUFFER_ADD ("%"PRIu64, CDTIME_T_TO_MS (vl->time)); - BUFFER_ADD (","); - BUFFER_ADD ("%"PRIu64, vl->values[ds_idx].absolute); - } - else - { - ERROR ("format_kairosdb: Unknown data source type: %i", - ds->ds[ds_idx].type); - sfree (rates); - return (-1); - } - BUFFER_ADD ("]]"); + BUFFER_ADD("]]"); #undef BUFFER_ADD - DEBUG ("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer); + DEBUG("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer); sfree(rates); - return (0); + return 0; } /* }}} int values_to_kairosdb */ -static int value_list_to_kairosdb (char *buffer, size_t buffer_size, /* {{{ */ - const data_set_t *ds, const value_list_t *vl, int store_rates) -{ +static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ + const data_set_t *ds, const value_list_t *vl, + int store_rates, + char const *const *http_attrs, + size_t http_attrs_num, int data_ttl, + char const *metrics_prefix) { char temp[512]; size_t offset = 0; int status; - memset (buffer, 0, buffer_size); - -#define BUFFER_ADD(...) do { \ - status = ssnprintf (buffer + offset, buffer_size - offset, \ - __VA_ARGS__); \ - if (status < 1) \ - return (-1); \ - else if (((size_t) status) >= (buffer_size - offset)) \ - return (-ENOMEM); \ - else \ - offset += ((size_t) status); \ -} while (0) - -#define BUFFER_ADD_KEYVAL(key, value) do { \ - status = kairosdb_escape_string (temp, sizeof (temp), (value)); \ - if (status != 0) \ - return (status); \ - BUFFER_ADD (",\"%s\": %s", (key), temp); \ -} while (0) - - for (size_t i = 0; i < ds->ds_num; i++) - { + memset(buffer, 0, buffer_size); + +#define BUFFER_ADD(...) \ + do { \ + status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \ + if (status < 1) \ + return -1; \ + else if (((size_t)status) >= (buffer_size - offset)) \ + return -ENOMEM; \ + else \ + offset += ((size_t)status); \ + } while (0) + +#define BUFFER_ADD_KEYVAL(key, value) \ + do { \ + status = kairosdb_escape_string(temp, sizeof(temp), (value)); \ + if (status != 0) \ + return status; \ + BUFFER_ADD(",\"%s\": %s", (key), temp); \ + } while (0) + + for (size_t i = 0; i < ds->ds_num; i++) { /* All value lists have a leading comma. The first one will be replaced with * a square bracket in `format_kairosdb_finalize'. */ - BUFFER_ADD (",{"); + BUFFER_ADD(",{\"name\":\""); - BUFFER_ADD ("\"name\":\"collectd"); + if (metrics_prefix != NULL) { + BUFFER_ADD("%s.", metrics_prefix); + } - BUFFER_ADD (".%s", vl->plugin); + BUFFER_ADD("%s", vl->plugin); - status = values_to_kairosdb (temp, sizeof (temp), ds, vl, store_rates, i); + status = values_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, i); if (status != 0) - return (status); + return status; - BUFFER_ADD ("\", \"datapoints\": %s", temp); + BUFFER_ADD("\", \"datapoints\": %s", temp); /* * Now adds meta data to metric as tags */ - memset (temp, 0, sizeof(temp)); + memset(temp, 0, sizeof(temp)); + + if (data_ttl != 0) + BUFFER_ADD(", \"ttl\": %i", data_ttl); - BUFFER_ADD (", \"tags\":\{"); + BUFFER_ADD(", \"tags\":\{"); + + BUFFER_ADD("\"host\": \"%s\"", vl->host); + for (size_t j = 0; j < http_attrs_num; j += 2) { + BUFFER_ADD(", \"%s\":", http_attrs[j]); + BUFFER_ADD(" \"%s\"", http_attrs[j + 1]); + } - BUFFER_ADD ("\"host\": \"%s\"", vl->host); if (strlen(vl->plugin_instance)) - BUFFER_ADD_KEYVAL ("plugin_instance", vl->plugin_instance); - BUFFER_ADD_KEYVAL ("type", vl->type); + BUFFER_ADD_KEYVAL("plugin_instance", vl->plugin_instance); + BUFFER_ADD_KEYVAL("type", vl->type); if (strlen(vl->type_instance)) - BUFFER_ADD_KEYVAL ("type_instance", vl->type_instance); + BUFFER_ADD_KEYVAL("type_instance", vl->type_instance); if (ds->ds_num != 1) - BUFFER_ADD_KEYVAL ("ds", ds->ds[i].name); - BUFFER_ADD ("}}"); + BUFFER_ADD_KEYVAL("ds", ds->ds[i].name); + BUFFER_ADD("}}"); } /* for ds->ds_num */ #undef BUFFER_ADD_KEYVAL #undef BUFFER_ADD - DEBUG ("format_kairosdb: value_list_to_kairosdb: buffer = %s;", buffer); + DEBUG("format_kairosdb: value_list_to_kairosdb: buffer = %s;", buffer); - return (0); + return 0; } /* }}} int value_list_to_kairosdb */ -static int format_kairosdb_value_list_nocheck (char *buffer, /* {{{ */ - size_t *ret_buffer_fill, size_t *ret_buffer_free, - const data_set_t *ds, const value_list_t *vl, - int store_rates, size_t temp_size) -{ +static int format_kairosdb_value_list_nocheck( + char *buffer, /* {{{ */ + size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, + const value_list_t *vl, int store_rates, size_t temp_size, + char const *const *http_attrs, size_t http_attrs_num, int data_ttl, + char const *metrics_prefix) { char temp[temp_size]; int status; - status = value_list_to_kairosdb (temp, sizeof (temp), ds, vl, store_rates); + status = value_list_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, + http_attrs, http_attrs_num, data_ttl, + metrics_prefix); if (status != 0) - return (status); - temp_size = strlen (temp); + return status; + temp_size = strlen(temp); - memcpy (buffer + (*ret_buffer_fill), temp, temp_size + 1); + memcpy(buffer + (*ret_buffer_fill), temp, temp_size + 1); (*ret_buffer_fill) += temp_size; (*ret_buffer_free) -= temp_size; - return (0); + return 0; } /* }}} int format_kairosdb_value_list_nocheck */ -int format_kairosdb_initialize (char *buffer, /* {{{ */ - size_t *ret_buffer_fill, size_t *ret_buffer_free) -{ +int format_kairosdb_initialize(char *buffer, /* {{{ */ + size_t *ret_buffer_fill, + size_t *ret_buffer_free) { size_t buffer_fill; size_t buffer_free; - if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL)) - return (-EINVAL); + if ((buffer == NULL) || (ret_buffer_fill == NULL) || + (ret_buffer_free == NULL)) + return -EINVAL; buffer_fill = *ret_buffer_fill; buffer_free = *ret_buffer_free; @@ -322,57 +302,59 @@ int format_kairosdb_initialize (char *buffer, /* {{{ */ buffer_fill = 0; if (buffer_free < 3) - return (-ENOMEM); + return -ENOMEM; - memset (buffer, 0, buffer_free); + memset(buffer, 0, buffer_free); *ret_buffer_fill = buffer_fill; *ret_buffer_free = buffer_free; - return (0); + return 0; } /* }}} int format_kairosdb_initialize */ -int format_kairosdb_finalize (char *buffer, /* {{{ */ - size_t *ret_buffer_fill, size_t *ret_buffer_free) -{ +int format_kairosdb_finalize(char *buffer, /* {{{ */ + size_t *ret_buffer_fill, size_t *ret_buffer_free) { size_t pos; - if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL)) - return (-EINVAL); + if ((buffer == NULL) || (ret_buffer_fill == NULL) || + (ret_buffer_free == NULL)) + return -EINVAL; if (*ret_buffer_free < 2) - return (-ENOMEM); + return -ENOMEM; /* Replace the leading comma added in `value_list_to_kairosdb' with a square * bracket. */ if (buffer[0] != ',') - return (-EINVAL); + return -EINVAL; buffer[0] = '['; pos = *ret_buffer_fill; buffer[pos] = ']'; - buffer[pos+1] = 0; + buffer[pos + 1] = 0; (*ret_buffer_fill)++; (*ret_buffer_free)--; - return (0); + return 0; } /* }}} int format_kairosdb_finalize */ -int format_kairosdb_value_list (char *buffer, /* {{{ */ - size_t *ret_buffer_fill, size_t *ret_buffer_free, - const data_set_t *ds, const value_list_t *vl, int store_rates) -{ - if ((buffer == NULL) - || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL) - || (ds == NULL) || (vl == NULL)) - return (-EINVAL); +int format_kairosdb_value_list(char *buffer, /* {{{ */ + size_t *ret_buffer_fill, size_t *ret_buffer_free, + const data_set_t *ds, const value_list_t *vl, + int store_rates, char const *const *http_attrs, + size_t http_attrs_num, int data_ttl, + char const *metrics_prefix) { + if ((buffer == NULL) || (ret_buffer_fill == NULL) || + (ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL)) + return -EINVAL; if (*ret_buffer_free < 3) - return (-ENOMEM); + return -ENOMEM; - return (format_kairosdb_value_list_nocheck (buffer, - ret_buffer_fill, ret_buffer_free, ds, vl, - store_rates, (*ret_buffer_free) - 2)); + return format_kairosdb_value_list_nocheck( + buffer, ret_buffer_fill, ret_buffer_free, ds, vl, store_rates, + (*ret_buffer_free) - 2, http_attrs, http_attrs_num, data_ttl, + metrics_prefix); } /* }}} int format_kairosdb_value_list */ /* vim: set sw=2 sts=2 et fdm=marker : */