diff options
author | Vladimir Kobal <vlad@prokk.net> | 2020-01-09 12:51:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-09 12:51:41 +0200 |
commit | 0fba85e2c20add69546cefbf37bb2033d2d1e052 (patch) | |
tree | dd124104fb54f99ef2ddca7e92e946d2d7f7aa31 /exporting/graphite | |
parent | 37edc6898b453b80806f07264cc94acf04bdd39e (diff) |
Send host labels via exporting connectors (#7554)
* Add labels to the JSON exporting connector
* Add labels to the Graphite exporting connector
* Add labels to the OpenTSDB telnet exporting connector
* Add labels to the OpenTSDB HTTP exporting connector
* Replace control characters in JSON strings
* Add unit tests
Diffstat (limited to 'exporting/graphite')
-rw-r--r-- | exporting/graphite/graphite.c | 64 | ||||
-rw-r--r-- | exporting/graphite/graphite.h | 4 |
2 files changed, 64 insertions, 4 deletions
diff --git a/exporting/graphite/graphite.c b/exporting/graphite/graphite.c index ec36b298e4..71f833a018 100644 --- a/exporting/graphite/graphite.c +++ b/exporting/graphite/graphite.c @@ -28,7 +28,7 @@ int init_graphite_connector(struct connector *connector) int init_graphite_instance(struct instance *instance) { instance->start_batch_formatting = NULL; - instance->start_host_formatting = NULL; + instance->start_host_formatting = format_host_labels_graphite_plaintext; instance->start_chart_formatting = NULL; if (EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AS_COLLECTED) @@ -37,7 +37,7 @@ int init_graphite_instance(struct instance *instance) instance->metric_formatting = format_dimension_stored_graphite_plaintext; instance->end_chart_formatting = NULL; - instance->end_host_formatting = NULL; + instance->end_host_formatting = flush_host_labels; instance->end_batch_formatting = NULL; instance->buffer = (void *)buffer_create(0); @@ -52,6 +52,60 @@ int init_graphite_instance(struct instance *instance) } /** + * Copy a label value and substitute underscores in place of charachters which can't be used in Graphite output + * + * @param dst a destination string. + * @param src a source string. + * @param len the maximum number of characters copied. + */ + +void sanitize_graphite_label_value(char *dst, char *src, size_t len) +{ + while (*src != '\0' && len) { + if (isspace(*src) || *src == ';' || *src == '~') + *dst++ = '_'; + else + *dst++ = *src; + src++; + len--; + } + *dst = '\0'; +} + +/** + * Format host labels for JSON connector + * + * @param instance an instance data structure. + * @param host a data collecting host. + * @return Always returns 0. + */ +int format_host_labels_graphite_plaintext(struct instance *instance, RRDHOST *host) +{ + if (!instance->labels) + instance->labels = buffer_create(1024); + + if (unlikely(!sending_labels_configured(instance))) + return 0; + + netdata_rwlock_rdlock(&host->labels_rwlock); + for (struct label *label = host->labels; label; label = label->next) { + if (!should_send_label(instance, label)) + continue; + + char value[CONFIG_MAX_VALUE + 1]; + sanitize_graphite_label_value(value, label->value, CONFIG_MAX_VALUE); + + if (*value) { + buffer_strcat(instance->labels, ";"); + buffer_sprintf(instance->labels, "%s=%s", label->key, value); + } + } + netdata_rwlock_unlock(&host->labels_rwlock); + + return 0; +} + +/** * Format dimension using collected data for Graphite connector * * @param instance an instance data structure. @@ -78,13 +132,14 @@ int format_dimension_collected_graphite_plaintext(struct instance *instance, RRD buffer_sprintf( instance->buffer, - "%s.%s.%s.%s%s%s " COLLECTED_NUMBER_FORMAT " %llu\n", + "%s.%s.%s.%s%s%s%s " COLLECTED_NUMBER_FORMAT " %llu\n", engine->config.prefix, engine->config.hostname, chart_name, dimension_name, (host->tags) ? ";" : "", (host->tags) ? host->tags : "", + (instance->labels) ? buffer_tostring(instance->labels) : "", rd->last_collected_value, (unsigned long long)rd->last_collected_time.tv_sec); @@ -124,13 +179,14 @@ int format_dimension_stored_graphite_plaintext(struct instance *instance, RRDDIM buffer_sprintf( instance->buffer, - "%s.%s.%s.%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n", + "%s.%s.%s.%s%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n", engine->config.prefix, engine->config.hostname, chart_name, dimension_name, (host->tags) ? ";" : "", (host->tags) ? host->tags : "", + (instance->labels) ? buffer_tostring(instance->labels) : "", value, (unsigned long long)last_t); diff --git a/exporting/graphite/graphite.h b/exporting/graphite/graphite.h index e5a2001c28..cc3767003a 100644 --- a/exporting/graphite/graphite.h +++ b/exporting/graphite/graphite.h @@ -7,6 +7,10 @@ int init_graphite_connector(struct connector *connector); int init_graphite_instance(struct instance *instance); + +void sanitize_graphite_label_value(char *dst, char *src, size_t len); +int format_host_labels_graphite_plaintext(struct instance *instance, RRDHOST *host); + int format_dimension_collected_graphite_plaintext(struct instance *instance, RRDDIM *rd); int format_dimension_stored_graphite_plaintext(struct instance *instance, RRDDIM *rd); |