diff options
Diffstat (limited to 'exporting/prometheus/prometheus.c')
-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 24bd215f4..0e0e8abf0 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,19 +509,31 @@ 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) buffer_sprintf(wb, "_%s", p->dimension); - buffer_sprintf(wb, "%s{chart=\"%s\",family=\"%s\"", p->suffix, p->chart, p->family); + buffer_sprintf(wb, "%s{chart=\"%s\"", p->suffix, p->chart); if (homogeneous) buffer_sprintf(wb, ",dimension=\"%s\"", p->dimension); + 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) @@ -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\",family=\"%s\",dimension=\"%s\"%s} " NETDATA_DOUBLE_FORMAT + "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT " %llu\n", prefix, context, units, suffix, - chart, - family, - dimension, + buffer_tostring(plabels.labels_buffer), labels, value, last_time * MSEC_PER_SEC); else buffer_sprintf( wb, - "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " NETDATA_DOUBLE_FORMAT + "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT "\n", prefix, context, units, suffix, - chart, - family, - dimension, + buffer_tostring(plabels.labels_buffer), labels, value); } |