From: Florian Forster Date: Sun, 21 Jun 2020 14:46:02 +0000 (+0200) Subject: format_graphite: Basically a rewrite for metric_t. X-Git-Tag: 6.0.0-rc0~144^2~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3e1dde5c48bca69c441fa3b15c94b174048d626;p=thirdparty%2Fcollectd.git format_graphite: Basically a rewrite for metric_t. --- diff --git a/Makefile.am b/Makefile.am index d468b19c3..c5576f776 100644 --- a/Makefile.am +++ b/Makefile.am @@ -134,6 +134,7 @@ noinst_LTLIBRARIES = \ libformat_graphite.la \ libformat_json.la \ libheap.la \ + libidentity.la \ libignorelist.la \ liblatency.la \ libllist.la \ @@ -270,6 +271,7 @@ collectd_LDADD = \ libavltree.la \ libcommon.la \ libheap.la \ + libidentity.la \ libllist.la \ libmetric.la \ liboconfig.la \ @@ -442,6 +444,11 @@ libheap_la_SOURCES = \ src/utils/heap/heap.c \ src/utils/heap/heap.h +libidentity_la_SOURCES = \ + src/daemon/identity.c \ + src/daemon/identity.h +libidentity_la_LIBADD = libavltree.la $(COMMON_LIBS) + libignorelist_la_SOURCES = \ src/utils/ignorelist/ignorelist.c \ src/utils/ignorelist/ignorelist.h @@ -473,12 +480,14 @@ libplugin_mock_la_LIBADD = libcommon.la libignorelist.la $(COMMON_LIBS) libformat_graphite_la_SOURCES = \ src/utils/format_graphite/format_graphite.c \ src/utils/format_graphite/format_graphite.h +libformat_graphite_la_LIBADD = libstrbuf.la $(COMMON_LIBS) test_format_graphite_SOURCES = \ src/utils/format_graphite/format_graphite_test.c \ src/testing.h test_format_graphite_LDADD = \ libformat_graphite.la \ + libidentity.la \ libmetadata.la \ libplugin_mock.la \ -lm diff --git a/src/utils/format_graphite/format_graphite.c b/src/utils/format_graphite/format_graphite.c index 6e671c49e..2eedf0ddf 100644 --- a/src/utils/format_graphite/format_graphite.c +++ b/src/utils/format_graphite/format_graphite.c @@ -25,9 +25,8 @@ #include "collectd.h" #include "plugin.h" -#include "utils/common/common.h" #include "utils/avltree/avltree.h" - +#include "utils/common/common.h" #include "utils/format_graphite/format_graphite.h" #include "utils_cache.h" @@ -36,277 +35,111 @@ /* Utils functions to format data sets in graphite format. * Largely taken from write_graphite.c as it remains the same formatting */ -static int gr_format_values(char *ret, size_t ret_len, const metric_t *metric_p, - gauge_t rate) { - size_t offset = 0; - int status; - - memset(ret, 0, ret_len); - -#define BUFFER_ADD(...) \ - do { \ - status = snprintf(ret + offset, ret_len - offset, __VA_ARGS__); \ - if (status < 1) { \ - return -1; \ - } else if (((size_t)status) >= (ret_len - offset)) { \ - return -1; \ - } else \ - offset += ((size_t)status); \ - } while (0) - - if (metric_p->value_type == DS_TYPE_GAUGE) - BUFFER_ADD(GAUGE_FORMAT, metric_p->value.gauge); +static int gr_format_values(strbuf_t *buf, const metric_t *m, gauge_t rate) { + if (m->value_type == DS_TYPE_GAUGE) + return strbuf_printf(buf, GAUGE_FORMAT, m->value.gauge); else if (rate != -1) - BUFFER_ADD("%f", rate); - else if (metric_p->value_type == DS_TYPE_COUNTER) - BUFFER_ADD("%" PRIu64, (uint64_t)metric_p->value.counter); - else if (metric_p->value_type == DS_TYPE_DERIVE) - BUFFER_ADD("%" PRIi64, metric_p->value.derive); - else { - P_ERROR("gr_format_values: Unknown data source type: %i", - metric_p->value_type); - return -1; - } - -#undef BUFFER_ADD - - return 0; + return strbuf_printf(buf, "%f", rate); + else if (m->value_type == DS_TYPE_COUNTER) + return strbuf_printf(buf, "%" PRIu64, (uint64_t)m->value.counter); + else if (m->value_type == DS_TYPE_DERIVE) + return strbuf_printf(buf, "%" PRIi64, m->value.derive); + + P_ERROR("gr_format_values: Unknown data source type: %d", m->value_type); + return EINVAL; } -static void gr_copy_escape_part(char *dst, const char *src, size_t dst_len, - char escape_char, bool preserve_separator) { - if (src == NULL) - return; - - for (size_t i = 0; i < dst_len; i++) { - if (src[i] == 0) { - dst[i] = 0; - break; - } - - if ((!preserve_separator && (src[i] == '.')) || ((src[i] == '/')) || - isspace((int)src[i]) || iscntrl((int)src[i])) - dst[i] = escape_char; - else - dst[i] = src[i]; +static int graphite_print_escaped(strbuf_t *buf, char const *s, + char escape_char) { + if ((buf == NULL) || (s == NULL)) { + return EINVAL; } -} -static int gr_format_name_tagged(char *ret, int ret_len, - metric_t const *metric_p, char const *prefix, - char const *postfix, char const escape_char, - unsigned int flags) { - int starting_len = ret_len; - if (prefix == NULL) - prefix = ""; - - if (postfix == NULL) - postfix = ""; - - memset(ret, 0, ret_len); - - int tmp_str_len = 0; - tmp_str_len = strlen(prefix); - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, "%s", prefix); - ret += tmp_str_len; /* This is the location of the trailing nul */ - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, "%s", prefix); - return starting_len; - } - - tmp_str_len = strlen(metric_p->identity->name); - if (tmp_str_len < ret_len) { - gr_copy_escape_part(ret, metric_p->identity->name, tmp_str_len + 1, - escape_char, 1); - ret += tmp_str_len; - ret_len -= tmp_str_len; - } else { - gr_copy_escape_part(ret, metric_p->identity->name, ret_len, escape_char, 1); - return starting_len; - } + size_t s_len = strlen(s); + while (s_len > 0) { + size_t valid_len = strcspn(s, GRAPHITE_FORBIDDEN); + if (valid_len == s_len) { + return strbuf_print(buf, s); + } + if (valid_len != 0) { + char tmp[valid_len + 1]; + strncpy(tmp, s, valid_len); + tmp[valid_len] = 0; + int status = strbuf_print(buf, tmp); + if (status != 0) { + return status; + } - tmp_str_len = strlen(postfix); - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, "%s", postfix); - ret += tmp_str_len; /* This is the location of the trailing nul */ - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, "%s", postfix); - return starting_len; - } + s += valid_len; + s_len -= valid_len; + continue; + } - if (metric_p->identity->root_p != NULL) { - c_avl_iterator_t *iter_p = c_avl_get_iterator(metric_p->identity->root_p); - if (iter_p != NULL) { - char *key_p = NULL; - char *value_p = NULL; - while ((c_avl_iterator_next(iter_p, (void **)&key_p, - (void **)&value_p)) == 0) { - if ((key_p != NULL) && (value_p != NULL)) { - tmp_str_len = strlen(key_p) + strlen(value_p) + 2; - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, ";%s=%s", key_p, value_p); - ret += tmp_str_len; - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, ";%s=%s", key_p, value_p); - return starting_len; - } - } - } - c_avl_iterator_destroy(iter_p); + char tmp[2] = {escape_char, 0}; + int status = strbuf_print(buf, tmp); + if (status != 0) { + return status; } + + s++; + s_len--; } - return starting_len - ret_len; /* Characters appended */ + return 0; } -static int gr_format_name(char *ret, int ret_len, metric_t const *metric_p, - char const *prefix, char const *postfix, - char const escape_char, unsigned int flags) { - int starting_len = ret_len; - if (prefix == NULL) - prefix = ""; - - if (postfix == NULL) - postfix = ""; - - memset(ret, 0, ret_len); - - int tmp_str_len = 0; - tmp_str_len = strlen(prefix); - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, "%s", prefix); - ret += tmp_str_len; /* This is the location of the trailing nul */ - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, "%s", prefix); - return starting_len; +static int gr_format_name(strbuf_t *buf, metric_t const *m, char const *prefix, + char const *suffix, char const escape_char, + unsigned int flags) { + if (prefix != NULL) { + strbuf_print(buf, prefix); } - - tmp_str_len = strlen(metric_p->identity->name); - if (tmp_str_len < ret_len) { - gr_copy_escape_part(ret, metric_p->identity->name, tmp_str_len + 1, - escape_char, 1); - ret += tmp_str_len; - ret_len -= tmp_str_len; - } else { - gr_copy_escape_part(ret, metric_p->identity->name, ret_len, escape_char, 1); - return starting_len; + graphite_print_escaped(buf, m->identity->name, escape_char); + if (suffix != NULL) { + strbuf_print(buf, suffix); } - tmp_str_len = strlen(postfix); - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, "%s", postfix); - ret += tmp_str_len; /* This is the location of the trailing nul */ - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, "%s", postfix); - return starting_len; + c_avl_iterator_t *iter = c_avl_get_iterator(m->identity->labels); + char *k = NULL, *v = NULL; + while ((c_avl_iterator_next(iter, (void **)&k, (void **)&v)) == 0) { + strbuf_print(buf, "."); + graphite_print_escaped(buf, k, escape_char); + strbuf_print(buf, (flags & GRAPHITE_SEPARATE_INSTANCES) ? "." : "="); + graphite_print_escaped(buf, v, escape_char); } + c_avl_iterator_destroy(iter); - if (metric_p->identity->root_p != NULL) { - c_avl_iterator_t *iter_p = c_avl_get_iterator(metric_p->identity->root_p); - if (iter_p != NULL) { - char *key_p = NULL; - char *value_p = NULL; - while ((c_avl_iterator_next(iter_p, (void **)&key_p, - (void **)&value_p)) == 0) { - if ((key_p != NULL) && (value_p != NULL)) { - tmp_str_len = strlen(value_p) + 1; - if (tmp_str_len < ret_len) { - snprintf(ret, tmp_str_len + 1, ";%s", value_p); - ret += tmp_str_len; - ret_len -= tmp_str_len; - } else { - snprintf(ret, ret_len, ";%s", value_p); - return starting_len; - } - } - } - c_avl_iterator_destroy(iter_p); - } - } - - return starting_len - ret_len; /* Characters appended */ -} - -static void escape_graphite_string(char *buffer, char escape_char) { - assert(strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL); - - for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN); *head != '\0'; - head += strcspn(head, GRAPHITE_FORBIDDEN)) - *head = escape_char; + return 0; } -int format_graphite(char *buffer, size_t buffer_size, metric_t const *metric_p, - char const *prefix, char const *postfix, - char const escape_char, unsigned int flags) { - int status = 0; - int buffer_pos = 0; - +int format_graphite(strbuf_t *buf, metric_t const *m, char const *prefix, + char const *postfix, char const escape_char, + unsigned int flags) { gauge_t rate = -1; if (flags & GRAPHITE_STORE_RATES) { - status = uc_get_rate(metric_p, &rate); + int status = uc_get_rate(m, &rate); if (status != 0) { P_ERROR("format_graphite: error with uc_get_rate"); return -1; } } - char key[10 * DATA_MAX_NAME_LEN]; - char values[512]; - size_t message_len; - char message[1024]; + /* format: + *