diff options
author | thiagoftsm <thiagoftsm@gmail.com> | 2023-05-24 19:19:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-24 22:19:16 +0300 |
commit | e39e809ac63eb73376c5fde1c769fb8c3915a8e7 (patch) | |
tree | 80289290a97eec095c579de74736a003919546af /exporting/prometheus | |
parent | 04742049a5b04ba5f4e6e7f13f8ab1ee1b34da8d (diff) |
Add chart labels to Prometheus. (#15099)
Diffstat (limited to 'exporting/prometheus')
-rw-r--r-- | exporting/prometheus/prometheus.c | 85 |
1 files changed, 73 insertions, 12 deletions
diff --git a/exporting/prometheus/prometheus.c b/exporting/prometheus/prometheus.c index 7a1112abdd..0e0e8abf01 100644 --- a/exporting/prometheus/prometheus.c +++ b/exporting/prometheus/prometheus.c @@ -326,6 +326,53 @@ void format_host_labels_prometheus(struct instance *instance, RRDHOST *host) rrdlabels_walkthrough_read(host->rrdlabels, format_prometheus_label_callback, &tmp); } +/** + * Format host labels for the Prometheus exporter + * We are using a structure instead a direct buffer to expand options quickly. + * + * @param labels_buffer is the buffer used to add labels. + */ + +struct format_prometheus_chart_label_callback { + BUFFER *labels_buffer; +}; + +static int format_prometheus_chart_label_callback(const char *name, const char *value, RRDLABEL_SRC ls, void *data) { + struct format_prometheus_chart_label_callback *d = (struct format_prometheus_chart_label_callback *)data; + + (void)ls; + + if (name[0] == '_' ) + return 1; + + char k[PROMETHEUS_ELEMENT_MAX + 1]; + char v[PROMETHEUS_ELEMENT_MAX + 1]; + + prometheus_name_copy(k, name, PROMETHEUS_ELEMENT_MAX); + prometheus_label_copy(v, value, PROMETHEUS_ELEMENT_MAX); + + if (*k && *v) { + buffer_sprintf(d->labels_buffer, ",%s=\"%s\"", k, v); + } + return 1; +} + +void format_chart_labels_prometheus(struct format_prometheus_chart_label_callback *plabel, + const char *chart, + const char *family, + const char *dim, + RRDSET *st) +{ + if (likely(plabel->labels_buffer)) + buffer_reset(plabel->labels_buffer); + else { + plabel->labels_buffer = buffer_create(1024, NULL); + } + buffer_sprintf(plabel->labels_buffer, "chart=\"%s\",dimension=\"%s\",family=\"%s\"", chart, dim, family); + + rrdlabels_walkthrough_read(st->rrdlabels, format_prometheus_chart_label_callback, plabel); +} + struct host_variables_callback_options { RRDHOST *host; BUFFER *wb; @@ -462,9 +509,17 @@ static void generate_as_collected_prom_help(BUFFER *wb, struct gen_parameters *p * @param p parameters for generating the metric string. * @param homogeneous a flag for homogeneous charts. * @param prometheus_collector a flag for metrics from prometheus collector. + * @param chart_labels the dictionary with chart labels */ -static void generate_as_collected_prom_metric(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector) +static void generate_as_collected_prom_metric(BUFFER *wb, + struct gen_parameters *p, + int homogeneous, + int prometheus_collector, + DICTIONARY *chart_labels) { + struct format_prometheus_chart_label_callback local_label; + local_label.labels_buffer = wb; + buffer_sprintf(wb, "%s_%s", p->prefix, p->context); if (!homogeneous) @@ -475,7 +530,11 @@ static void generate_as_collected_prom_metric(BUFFER *wb, struct gen_parameters if (homogeneous) buffer_sprintf(wb, ",dimension=\"%s\"", p->dimension); - buffer_sprintf(wb, ",family=\"%s\"%s} ", p->family, p->labels); + buffer_sprintf(wb, ",family=\"%s\"", p->family); + + rrdlabels_walkthrough_read(chart_labels, format_prometheus_chart_label_callback, &local_label); + + buffer_sprintf(wb, "%s} ", p->labels); if (prometheus_collector) buffer_sprintf( @@ -564,6 +623,10 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( // for each chart RRDSET *st; + + static struct format_prometheus_chart_label_callback plabels = { + .labels_buffer = NULL, + }; rrdset_foreach_read(st, host) { if (likely(can_send_rrdset(instance, st, filter))) { @@ -655,7 +718,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES)) buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, p.type); - generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector); + generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector, st->rrdlabels); } else { // the dimensions of the chart, do not have the same algorithm, multiplier or divisor @@ -673,7 +736,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( buffer_sprintf( wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, p.type); - generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector); + generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector, st->rrdlabels); } } else { @@ -694,6 +757,8 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd), PROMETHEUS_ELEMENT_MAX); + format_chart_labels_prometheus(&plabels, chart, family, dimension, st); + if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP)) buffer_sprintf( wb, @@ -713,30 +778,26 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) buffer_sprintf( wb, - "%s_%s%s%s{chart=\"%s\",dimension=\"%s\",family=\"%s\"%s} " NETDATA_DOUBLE_FORMAT + "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT " %llu\n", prefix, context, units, suffix, - chart, - dimension, - family, + buffer_tostring(plabels.labels_buffer), labels, value, last_time * MSEC_PER_SEC); else buffer_sprintf( wb, - "%s_%s%s%s{chart=\"%s\",dimension=\"%s\",family=\"%s\"%s} " NETDATA_DOUBLE_FORMAT + "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT "\n", prefix, context, units, suffix, - chart, - dimension, - family, + buffer_tostring(plabels.labels_buffer), labels, value); } |