Fix values in Prometheus export for metrics, collected by the Prometheus collector (#10551)
Vladimir Kobal committed
Jan 26, 2021 at 15:37 UTC
5ff4b8fdfafded3558aa6e9c78a675a60f0d2a57
1 file changed
+114
-91
exporting/prometheus/prometheus.c
+114
-91
@@ -382,6 +382,93 @@ static int print_host_variables(RRDVAR *rv, void *data)
382
return 0;
383
}
384
385
+struct gen_parameters {
386
+ const char *prefix;
387
+ char *context;
388
+ char *suffix;
389
+
390
+ char *chart;
391
+ char *dimension;
392
+ char *family;
393
+ char *labels;
394
+
395
+ PROMETHEUS_OUTPUT_OPTIONS output_options;
396
+ RRDSET *st;
397
+ RRDDIM *rd;
398
+
399
+ const char *relation;
400
+ const char *type;
401
+};
402
+
403
+/**
404
+ * Write an as-collected help comment to a buffer.
405
+ *
406
+ * @param wb the buffer to write the comment to.
407
+ * @param p parameters for generating the comment string.
408
+ * @param homogeneous a flag for homogeneous charts.
409
+ * @param prometheus_collector a flag for metrics from prometheus collector.
410
+ */
411
+static void generate_as_collected_prom_help(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector)
412
+{
413
+ buffer_sprintf(wb, "# COMMENT %s_%s", p->prefix, p->context);
414
+
415
+ if (!homogeneous)
416
+ buffer_sprintf(wb, "_%s", p->dimension);
417
+
418
+ buffer_sprintf(
419
+ wb,
420
+ "%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * ",
421
+ p->suffix,
422
+ (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->st->name) ? p->st->name : p->st->id,
423
+ p->st->context,
424
+ p->st->family,
425
+ (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->rd->name) ? p->rd->name : p->rd->id);
426
+
427
+ if (prometheus_collector)
428
+ buffer_sprintf(wb, "1 / 1");
429
+ else
430
+ buffer_sprintf(wb, COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT, p->rd->multiplier, p->rd->divisor);
431
+
432
+ buffer_sprintf(wb, " %s %s (%s)\n", p->relation, p->st->units, p->type);
433
+}
434
+
435
+/**
436
+ * Write an as-collected metric to a buffer.
437
+ *
438
+ * @param wb the buffer to write the metric to.
439
+ * @param p parameters for generating the metric string.
440
+ * @param homogeneous a flag for homogeneous charts.
441
+ * @param prometheus_collector a flag for metrics from prometheus collector.
442
+ */
443
+static void generate_as_collected_prom_metric(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector)
444
+{
445
+ buffer_sprintf(wb, "%s_%s", p->prefix, p->context);
446
+
447
+ if (!homogeneous)
448
+ buffer_sprintf(wb, "_%s", p->dimension);
449
+
450
+ buffer_sprintf(wb, "%s{chart=\"%s\",family=\"%s\"", p->suffix, p->chart, p->family);
451
+
452
+ if (homogeneous)
453
+ buffer_sprintf(wb, ",dimension=\"%s\"", p->dimension);
454
+
455
+ buffer_sprintf(wb, "%s} ", p->labels);
456
+
457
+ if (prometheus_collector)
458
+ buffer_sprintf(
459
+ wb,
460
+ CALCULATED_NUMBER_FORMAT,
461
+ (calculated_number)p->rd->last_collected_value * (calculated_number)p->rd->multiplier /
462
+ (calculated_number)p->rd->divisor);
463
+ else
464
+ buffer_sprintf(wb, COLLECTED_NUMBER_FORMAT, p->rd->last_collected_value);
465
+
466
+ if (p->output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
467
+ buffer_sprintf(wb, " %llu\n", timeval_msec(&p->rd->last_collected_time));
468
+ else
469
+ buffer_sprintf(wb, "\n");
470
+}
471
+
472
/**
473
* Write metrics in Prometheus format to a buffer.
474
*
@@ -514,12 +601,16 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
601
602
int as_collected = (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AS_COLLECTED);
603
int homogeneous = 1;
604
+ int prometheus_collector = 0;
605
if (as_collected) {
606
if (rrdset_flag_check(st, RRDSET_FLAG_HOMOGENEOUS_CHECK))
607
rrdset_update_heterogeneous_flag(st);
608
609
if (rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS))
610
homogeneous = 0;
611
+
612
+ if (st->module_name && !strcmp(st->module_name, "prometheus"))
613
+ prometheus_collector = 1;
614
} else {
615
if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE &&
616
!(output_options & PROMETHEUS_OUTPUT_HIDEUNITS))
@@ -548,15 +639,28 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
639
if (as_collected) {
640
// we need as-collected / raw data
641
642
+ struct gen_parameters p;
643
+ p.prefix = prefix;
644
+ p.context = context;
645
+ p.suffix = suffix;
646
+ p.chart = chart;
647
+ p.dimension = dimension;
648
+ p.family = family;
649
+ p.labels = labels;
650
+ p.output_options = output_options;
651
+ p.st = st;
652
+ p.rd = rd;
653
+
654
if (unlikely(rd->last_collected_time.tv_sec < instance->after))
655
continue;
656
554
- const char *t = "gauge", *h = "gives";
657
+ p.type = "gauge";
658
+ p.relation = "gives";
659
if (rd->algorithm == RRD_ALGORITHM_INCREMENTAL ||
660
rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
557
- t = "counter";
558
- h = "delta gives";
559
- suffix = "_total";
661
+ p.type = "counter";
662
+ p.relation = "delta gives";
663
+ p.suffix = "_total";
664
}
665
666
if (homogeneous) {
@@ -569,53 +673,12 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
673
PROMETHEUS_ELEMENT_MAX);
674
675
if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
572
- buffer_sprintf(
573
- wb,
574
- "# COMMENT %s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT
575
- " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n",
576
- prefix,
577
- context,
578
- suffix,
579
- (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id,
580
- st->context,
581
- st->family,
582
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id,
583
- rd->multiplier,
584
- rd->divisor,
585
- h,
586
- st->units,
587
- t);
676
+ generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
677
678
if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
590
- buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, t);
679
+ buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, p.type);
680
592
- if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
593
- buffer_sprintf(
594
- wb,
595
- "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT
596
- " %llu\n",
597
- prefix,
598
- context,
599
- suffix,
600
- chart,
601
- family,
602
- dimension,
603
- labels,
604
- rd->last_collected_value,
605
- timeval_msec(&rd->last_collected_time));
606
- else
607
- buffer_sprintf(
608
- wb,
609
- "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT
610
- "\n",
611
- prefix,
612
- context,
613
- suffix,
614
- chart,
615
- family,
616
- dimension,
617
- labels,
618
- rd->last_collected_value);
681
+ generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector);
682
} else {
683
// the dimensions of the chart, do not have the same algorithm, multiplier or divisor
684
// we create a metric per dimension
@@ -626,53 +689,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
689
PROMETHEUS_ELEMENT_MAX);
690
691
if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
629
- buffer_sprintf(
630
- wb,
631
- "# COMMENT %s_%s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT
632
- " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n",
633
- prefix,
634
- context,
635
- dimension,
636
- suffix,
637
- (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id,
638
- st->context,
639
- st->family,
640
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id,
641
- rd->multiplier,
642
- rd->divisor,
643
- h,
644
- st->units,
645
- t);
692
+ generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
693
694
if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
695
buffer_sprintf(
649
- wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, t);
696
+ wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, p.type);
697
651
- if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
652
- buffer_sprintf(
653
- wb,
654
- "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n",
655
- prefix,
656
- context,
657
- dimension,
658
- suffix,
659
- chart,
660
- family,
661
- labels,
662
- rd->last_collected_value,
663
- timeval_msec(&rd->last_collected_time));
664
- else
665
- buffer_sprintf(
666
- wb,
667
- "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT "\n",
668
- prefix,
669
- context,
670
- dimension,
671
- suffix,
672
- chart,
673
- family,
674
- labels,
675
- rd->last_collected_value);
698
+ generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector);
699
}
700
} else {
701
// we need average or sum of the data