diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-11-07 12:19:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-11-07 12:20:17 +0000 |
commit | a64a253794ac64cb40befee54db53bde17dd0d49 (patch) | |
tree | c1024acc5f6e508814b944d99f112259bb28b1be /backends/prometheus/backend_prometheus.c | |
parent | New upstream version 1.10.0+dfsg (diff) | |
download | netdata-upstream/1.11.0+dfsg.tar.xz netdata-upstream/1.11.0+dfsg.zip |
New upstream version 1.11.0+dfsgupstream/1.11.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | backends/prometheus/backend_prometheus.c (renamed from src/backend_prometheus.c) | 177 |
1 files changed, 132 insertions, 45 deletions
diff --git a/src/backend_prometheus.c b/backends/prometheus/backend_prometheus.c index bfcda9297..223b3f9f0 100644 --- a/src/backend_prometheus.c +++ b/backends/prometheus/backend_prometheus.c @@ -1,4 +1,7 @@ -#include "common.h" +// SPDX-License-Identifier: GPL-3.0-or-later + +#define BACKENDS_INTERNALS +#include "backend_prometheus.h" // ---------------------------------------------------------------------------- // PROMETHEUS @@ -109,8 +112,77 @@ static inline char *prometheus_units_copy(char *d, const char *s, size_t usable) #define PROMETHEUS_ELEMENT_MAX 256 #define PROMETHEUS_LABELS_MAX 1024 +#define PROMETHEUS_VARIABLE_MAX 256 + +struct host_variables_callback_options { + RRDHOST *host; + BUFFER *wb; + BACKEND_OPTIONS backend_options; + PROMETHEUS_OUTPUT_OPTIONS output_options; + const char *prefix; + const char *labels; + time_t now; + int host_header_printed; + char name[PROMETHEUS_VARIABLE_MAX+1]; +}; + +static int print_host_variables(RRDVAR *rv, void *data) { + struct host_variables_callback_options *opts = data; + + if(rv->options & (RRDVAR_OPTION_CUSTOM_HOST_VAR|RRDVAR_OPTION_CUSTOM_CHART_VAR)) { + if(!opts->host_header_printed) { + opts->host_header_printed = 1; + + if(opts->output_options & PROMETHEUS_OUTPUT_HELP) { + buffer_sprintf(opts->wb, "\n# COMMENT global host and chart variables\n"); + } + } + + calculated_number value = rrdvar2number(rv); + if(isnan(value) || isinf(value)) { + if(opts->output_options & PROMETHEUS_OUTPUT_HELP) + buffer_sprintf(opts->wb, "# COMMENT variable \"%s\" is %s. Skipped.\n", rv->name, (isnan(value))?"NAN":"INF"); + + return 0; + } + + char *label_pre = ""; + char *label_post = ""; + if(opts->labels && *opts->labels) { + label_pre = "{"; + label_post = "}"; + } -static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, const char *prefix, uint32_t options, time_t after, time_t before, int allhosts, int help, int types, int names, int timestamps) { + prometheus_name_copy(opts->name, rv->name, sizeof(opts->name)); + + if(opts->output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) + buffer_sprintf(opts->wb + , "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n" + , opts->prefix + , opts->name + , label_pre + , opts->labels + , label_post + , value + , ((rv->last_updated) ? rv->last_updated : opts->now) * 1000ULL + ); + else + buffer_sprintf(opts->wb, "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT "\n" + , opts->prefix + , opts->name + , label_pre + , opts->labels + , label_post + , value + ); + + return 1; + } + + return 0; +} + +static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, const char *prefix, BACKEND_OPTIONS backend_options, time_t after, time_t before, int allhosts, PROMETHEUS_OUTPUT_OPTIONS output_options) { rrdhost_rdlock(host); char hostname[PROMETHEUS_ELEMENT_MAX + 1]; @@ -118,13 +190,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER char labels[PROMETHEUS_LABELS_MAX + 1] = ""; if(allhosts) { - if(timestamps) + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS); else buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version); if(host->tags && *(host->tags)) { - if(timestamps) { + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) { buffer_sprintf(wb, "netdata_host_tags_info{instance=\"%s\",%s} 1 %llu\n", hostname, host->tags, now_realtime_usec() / USEC_PER_MS); // deprecated, exists only for compatibility with older queries @@ -142,13 +214,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER snprintfz(labels, PROMETHEUS_LABELS_MAX, ",instance=\"%s\"", hostname); } else { - if(timestamps) + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS); else buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version); if(host->tags && *(host->tags)) { - if(timestamps) { + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) { buffer_sprintf(wb, "netdata_host_tags_info{%s} 1 %llu\n", host->tags, now_realtime_usec() / USEC_PER_MS); // deprecated, exists only for compatibility with older queries @@ -163,6 +235,21 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER } } + // send custom variables set for the host + if(output_options & PROMETHEUS_OUTPUT_VARIABLES){ + struct host_variables_callback_options opts = { + .host = host, + .wb = wb, + .labels = (labels[0] == ',')?&labels[1]:labels, + .backend_options = backend_options, + .output_options = output_options, + .prefix = prefix, + .now = now_realtime_sec(), + .host_header_printed = 0 + }; + foreach_host_variable_callback(host, print_host_variables, &opts); + } + // for each chart RRDSET *st; rrdset_foreach_read(st, host) { @@ -171,14 +258,14 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER char family[PROMETHEUS_ELEMENT_MAX + 1]; char units[PROMETHEUS_ELEMENT_MAX + 1] = ""; - prometheus_label_copy(chart, (names && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX); + prometheus_label_copy(chart, (output_options & PROMETHEUS_OUTPUT_NAMES && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX); prometheus_label_copy(family, st->family, PROMETHEUS_ELEMENT_MAX); prometheus_name_copy(context, st->context, PROMETHEUS_ELEMENT_MAX); - if(likely(backends_can_send_rrdset(options, st))) { + if(likely(backends_can_send_rrdset(backend_options, st))) { rrdset_rdlock(st); - int as_collected = ((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED); + int as_collected = (BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED); int homogeneus = 1; if(as_collected) { if(rrdset_flag_check(st, RRDSET_FLAG_HOMEGENEOUS_CHECK)) @@ -188,14 +275,14 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER homogeneus = 0; } else { - if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE) + if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) prometheus_units_copy(units, st->units, PROMETHEUS_ELEMENT_MAX); } - if(unlikely(help)) + if(unlikely(output_options & PROMETHEUS_OUTPUT_HELP)) buffer_sprintf(wb, "\n# COMMENT %s chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n" , (homogeneus)?"homogeneus":"heterogeneous" - , (names && st->name) ? st->name : st->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id , st->context , st->family , st->units @@ -223,18 +310,18 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER // all the dimensions of the chart, has the same algorithm, multiplier and divisor // we add all dimensions as labels - prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); + prometheus_label_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - if(unlikely(help)) + if(unlikely(output_options & PROMETHEUS_OUTPUT_HELP)) buffer_sprintf(wb , "# COMMENT %s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n" , prefix , context , suffix - , (names && st->name) ? st->name : st->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id , st->context , st->family - , (names && rd->name) ? rd->name : rd->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id , rd->multiplier , rd->divisor , h @@ -242,7 +329,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER , t ); - if(unlikely(types)) + if(unlikely(output_options & PROMETHEUS_OUTPUT_TYPES)) buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s %s\n" , prefix , context @@ -250,7 +337,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER , t ); - if(timestamps) + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf(wb , "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n" , prefix @@ -280,19 +367,19 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER // the dimensions of the chart, do not have the same algorithm, multiplier or divisor // we create a metric per dimension - prometheus_name_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); + prometheus_name_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - if(unlikely(help)) + if(unlikely(output_options & PROMETHEUS_OUTPUT_HELP)) buffer_sprintf(wb , "# COMMENT %s_%s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n" , prefix , context , dimension , suffix - , (names && st->name) ? st->name : st->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id , st->context , st->family - , (names && rd->name) ? rd->name : rd->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id , rd->multiplier , rd->divisor , h @@ -300,7 +387,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER , t ); - if(unlikely(types)) + if(unlikely(output_options & PROMETHEUS_OUTPUT_TYPES)) buffer_sprintf(wb, "# COMMENT TYPE %s_%s_%s%s %s\n" , prefix , context @@ -309,7 +396,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER , t ); - if(timestamps) + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf(wb , "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n" , prefix @@ -340,30 +427,30 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER // we need average or sum of the data time_t first_t = after, last_t = before; - calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t); + calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t); if(!isnan(value) && !isinf(value)) { - if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE) + if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) suffix = "_average"; - else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_SUM) + else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM) suffix = "_sum"; - prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); + prometheus_label_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX); - if (unlikely(help)) + if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP)) buffer_sprintf(wb, "# COMMENT %s_%s%s%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n" , prefix , context , units , suffix - , (names && rd->name) ? rd->name : rd->id + , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id , st->units , (unsigned long long)first_t , (unsigned long long)last_t ); - if (unlikely(types)) + if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES)) buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s%s gauge\n" , prefix , context @@ -371,7 +458,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER , suffix ); - if(timestamps) + if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf(wb, "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n" , prefix , context @@ -408,32 +495,32 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER rrdhost_unlock(host); } -static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t options, const char *server, time_t now, int help) { +static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, BACKEND_OPTIONS backend_options, const char *server, time_t now, PROMETHEUS_OUTPUT_OPTIONS output_options) { if(!server || !*server) server = "default"; time_t after = prometheus_server_last_access(server, host, now); int first_seen = 0; if(!after) { - after = now - backend_update_every; + after = now - global_backend_update_every; first_seen = 1; } if(after > now) { // oops! this should never happen - after = now - backend_update_every; + after = now - global_backend_update_every; } - if(help) { + if(output_options & PROMETHEUS_OUTPUT_HELP) { int show_range = 1; char *mode; - if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED) { + if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) { mode = "as collected"; show_range = 0; } - else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE) + else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE) mode = "average"; - else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_SUM) + else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM) mode = "sum"; else mode = "unknown"; @@ -456,24 +543,24 @@ static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t return after; } -void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names, int timestamps) { +void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, PROMETHEUS_OUTPUT_OPTIONS output_options) { time_t before = now_realtime_sec(); // we start at the point we had stopped before - time_t after = prometheus_preparation(host, wb, options, server, before, help); + time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options); - rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, options, after, before, 0, help, types, names, timestamps); + rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 0, output_options); } -void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names, int timestamps) { +void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, PROMETHEUS_OUTPUT_OPTIONS output_options) { time_t before = now_realtime_sec(); // we start at the point we had stopped before - time_t after = prometheus_preparation(host, wb, options, server, before, help); + time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options); rrd_rdlock(); rrdhost_foreach_read(host) { - rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, options, after, before, 1, help, types, names, timestamps); + rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 1, output_options); } rrd_unlock(); } |