summaryrefslogtreecommitdiffstats
path: root/exporting
diff options
context:
space:
mode:
authorVladimir Kobal <vlad@prokk.net>2021-01-26 15:37:51 +0200
committerGitHub <noreply@github.com>2021-01-26 15:37:51 +0200
commit5ff4b8fdfafded3558aa6e9c78a675a60f0d2a57 (patch)
treee902fb2d7c8c75c787e11512724bd49c811b1e0c /exporting
parent1e2a5297a1e556080a9a3dc61a9ef28cd5488363 (diff)
Fix values in Prometheus export for metrics, collected by the Prometheus collector (#10551)
Diffstat (limited to 'exporting')
-rw-r--r--exporting/prometheus/prometheus.c205
1 files changed, 114 insertions, 91 deletions
diff --git a/exporting/prometheus/prometheus.c b/exporting/prometheus/prometheus.c
index 81a397aa34..371f5a5201 100644
--- a/exporting/prometheus/prometheus.c
+++ b/exporting/prometheus/prometheus.c
@@ -382,6 +382,93 @@ static int print_host_variables(RRDVAR *rv, void *data)
return 0;
}
+struct gen_parameters {
+ const char *prefix;
+ char *context;
+ char *suffix;
+
+ char *chart;
+ char *dimension;
+ char *family;
+ char *labels;
+
+ PROMETHEUS_OUTPUT_OPTIONS output_options;
+ RRDSET *st;
+ RRDDIM *rd;
+
+ const char *relation;
+ const char *type;
+};
+
+/**
+ * Write an as-collected help comment to a buffer.
+ *
+ * @param wb the buffer to write the comment to.
+ * @param p parameters for generating the comment string.
+ * @param homogeneous a flag for homogeneous charts.
+ * @param prometheus_collector a flag for metrics from prometheus collector.
+ */
+static void generate_as_collected_prom_help(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector)
+{
+ buffer_sprintf(wb, "# COMMENT %s_%s", p->prefix, p->context);
+
+ if (!homogeneous)
+ buffer_sprintf(wb, "_%s", p->dimension);
+
+ buffer_sprintf(
+ wb,
+ "%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * ",
+ p->suffix,
+ (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->st->name) ? p->st->name : p->st->id,
+ p->st->context,
+ p->st->family,
+ (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->rd->name) ? p->rd->name : p->rd->id);
+
+ if (prometheus_collector)
+ buffer_sprintf(wb, "1 / 1");
+ else
+ buffer_sprintf(wb, COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT, p->rd->multiplier, p->rd->divisor);
+
+ buffer_sprintf(wb, " %s %s (%s)\n", p->relation, p->st->units, p->type);
+}
+
+/**
+ * Write an as-collected metric to a buffer.
+ *
+ * @param wb the buffer to write the metric to.
+ * @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.
+ */
+static void generate_as_collected_prom_metric(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector)
+{
+ 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);
+
+ if (homogeneous)
+ buffer_sprintf(wb, ",dimension=\"%s\"", p->dimension);
+
+ buffer_sprintf(wb, "%s} ", p->labels);
+
+ if (prometheus_collector)
+ buffer_sprintf(
+ wb,
+ CALCULATED_NUMBER_FORMAT,
+ (calculated_number)p->rd->last_collected_value * (calculated_number)p->rd->multiplier /
+ (calculated_number)p->rd->divisor);
+ else
+ buffer_sprintf(wb, COLLECTED_NUMBER_FORMAT, p->rd->last_collected_value);
+
+ if (p->output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
+ buffer_sprintf(wb, " %llu\n", timeval_msec(&p->rd->last_collected_time));
+ else
+ buffer_sprintf(wb, "\n");
+}
+
/**
* Write metrics in Prometheus format to a buffer.
*
@@ -514,12 +601,16 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
int as_collected = (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AS_COLLECTED);
int homogeneous = 1;
+ int prometheus_collector = 0;
if (as_collected) {
if (rrdset_flag_check(st, RRDSET_FLAG_HOMOGENEOUS_CHECK))
rrdset_update_heterogeneous_flag(st);
if (rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS))
homogeneous = 0;
+
+ if (st->module_name && !strcmp(st->module_name, "prometheus"))
+ prometheus_collector = 1;
} else {
if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE &&
!(output_options & PROMETHEUS_OUTPUT_HIDEUNITS))
@@ -548,15 +639,28 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
if (as_collected) {
// we need as-collected / raw data
+ struct gen_parameters p;
+ p.prefix = prefix;
+ p.context = context;
+ p.suffix = suffix;
+ p.chart = chart;
+ p.dimension = dimension;
+ p.family = family;
+ p.labels = labels;
+ p.output_options = output_options;
+ p.st = st;
+ p.rd = rd;
+
if (unlikely(rd->last_collected_time.tv_sec < instance->after))
continue;
- const char *t = "gauge", *h = "gives";
+ p.type = "gauge";
+ p.relation = "gives";
if (rd->algorithm == RRD_ALGORITHM_INCREMENTAL ||
rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
- t = "counter";
- h = "delta gives";
- suffix = "_total";
+ p.type = "counter";
+ p.relation = "delta gives";
+ p.suffix = "_total";
}
if (homogeneous) {
@@ -569,53 +673,12 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
PROMETHEUS_ELEMENT_MAX);
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,
- (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id,
- st->context,
- st->family,
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id,
- rd->multiplier,
- rd->divisor,
- h,
- st->units,
- t);
+ generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
- buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, t);
+ buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, p.type);
- 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,
- context,
- suffix,
- chart,
- family,
- dimension,
- labels,
- rd->last_collected_value,
- timeval_msec(&rd->last_collected_time));
- else
- buffer_sprintf(
- wb,
- "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT
- "\n",
- prefix,
- context,
- suffix,
- chart,
- family,
- dimension,
- labels,
- rd->last_collected_value);
+ generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector);
} else {
// the dimensions of the chart, do not have the same algorithm, multiplier or divisor
// we create a metric per dimension
@@ -626,53 +689,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
PROMETHEUS_ELEMENT_MAX);
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,
- (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id,
- st->context,
- st->family,
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id,
- rd->multiplier,
- rd->divisor,
- h,
- st->units,
- t);
+ generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
buffer_sprintf(
- wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, t);
+ wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, p.type);
- if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
- buffer_sprintf(
- wb,
- "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n",
- prefix,
- context,
- dimension,
- suffix,
- chart,
- family,
- labels,
- rd->last_collected_value,
- timeval_msec(&rd->last_collected_time));
- else
- buffer_sprintf(
- wb,
- "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT "\n",
- prefix,
- context,
- dimension,
- suffix,
- chart,
- family,
- labels,
- rd->last_collected_value);
+ generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector);
}
} else {
// we need average or sum of the data