Compatibility with Prometheus HELP (#17191)
thiagoftsm committed
Mar 29, 2024 at 20:43 UTC
4680da48b91a40e48f802627b81a67d5a5270fbd
5 files changed
+277
-332
src/exporting/prometheus/prometheus.c
+272
-275
@@ -353,6 +353,7 @@ static int format_prometheus_chart_label_callback(const char *name, const char *
353
struct host_variables_callback_options {
354
RRDHOST *host;
355
BUFFER *wb;
356
+ BUFFER *plabels_buffer;
357
EXPORTING_OPTIONS exporting_options;
358
PROMETHEUS_OUTPUT_OPTIONS output_options;
359
const char *prefix;
@@ -360,6 +361,9 @@ struct host_variables_callback_options {
361
time_t now;
362
int host_header_printed;
363
char name[PROMETHEUS_VARIABLE_MAX + 1];
364
+ SIMPLE_PATTERN *pattern;
365
+ struct instance *instance;
366
+ STRING *prometheus;
367
};
368
369
/**
@@ -376,18 +380,10 @@ static int print_host_variables_callback(const DICTIONARY_ITEM *item __maybe_unu
380
381
if (!opts->host_header_printed) {
382
opts->host_header_printed = 1;
379
-
380
- if (opts->output_options & PROMETHEUS_OUTPUT_HELP) {
381
- buffer_sprintf(opts->wb, "\n# COMMENT global host and chart variables\n");
382
- }
383
}
384
385
NETDATA_DOUBLE value = rrdvar2number(rv);
386
if (isnan(value) || isinf(value)) {
387
- if (opts->output_options & PROMETHEUS_OUTPUT_HELP)
388
- buffer_sprintf(
389
- opts->wb, "# COMMENT variable \"%s\" is %s. Skipped.\n", rrdvar_name(rv), (isnan(value)) ? "NAN" : "INF");
390
-
387
return 0;
388
}
389
@@ -448,32 +444,32 @@ struct gen_parameters {
444
* Write an as-collected help comment to a buffer.
445
*
446
* @param wb the buffer to write the comment to.
451
- * @param p parameters for generating the comment string.
452
- * @param homogeneous a flag for homogeneous charts.
453
- * @param prometheus_collector a flag for metrics from prometheus collector.
447
+ * @param context context name we are using
448
*/
455
-static void generate_as_collected_prom_help(BUFFER *wb, struct gen_parameters *p, int homogeneous, int prometheus_collector)
449
+static inline void generate_as_collected_prom_help(BUFFER *wb,
450
+ const char *prefix,
451
+ char *context,
452
+ char *units,
453
+ char *suffix,
454
+ RRDSET *st)
455
{
457
- buffer_sprintf(wb, "# COMMENT %s_%s", p->prefix, p->context);
458
-
459
- if (!homogeneous)
460
- buffer_sprintf(wb, "_%s", p->dimension);
461
-
462
- buffer_sprintf(
463
- wb,
464
- "%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * ",
465
- p->suffix,
466
- (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->st->name) ? rrdset_name(p->st) : rrdset_id(p->st),
467
- rrdset_context(p->st),
468
- rrdset_family(p->st),
469
- (p->output_options & PROMETHEUS_OUTPUT_NAMES && p->rd->name) ? rrddim_name(p->rd) : rrddim_id(p->rd));
470
-
471
- if (prometheus_collector)
472
- buffer_sprintf(wb, "1 / 1");
473
- else
474
- buffer_sprintf(wb, "%d / %d", p->rd->multiplier, p->rd->divisor);
456
+ buffer_sprintf(wb, "# HELP %s_%s%s%s %s\n", prefix, context, units, suffix, rrdset_title(st));
457
+}
458
476
- buffer_sprintf(wb, " %s %s (%s)\n", p->relation, rrdset_units(p->st), p->type);
459
+/**
460
+ * Write an as-collected help comment to a buffer.
461
+ *
462
+ * @param wb the buffer to write the comment to.
463
+ * @param context context name we are using
464
+ */
465
+static inline void generate_as_collected_prom_type(BUFFER *wb,
466
+ const char *prefix,
467
+ char *context,
468
+ char *units,
469
+ char *suffix,
470
+ const char *type)
471
+{
472
+ buffer_sprintf(wb, "# TYPE %s_%s%s%s %s\n", prefix, context, units, suffix, type);
473
}
474
475
/**
@@ -485,7 +481,7 @@ static void generate_as_collected_prom_help(BUFFER *wb, struct gen_parameters *p
481
* @param prometheus_collector a flag for metrics from prometheus collector.
482
* @param chart_labels the dictionary with chart labels
483
*/
488
-static void generate_as_collected_prom_metric(BUFFER *wb,
484
+static void generate_as_collected_from_metric(BUFFER *wb,
485
struct gen_parameters *p,
486
int homogeneous,
487
int prometheus_collector,
@@ -602,6 +598,220 @@ static void prometheus_print_os_info(
598
599
fclose(fp);
600
}
601
+
602
+/**
603
+ * RRDSET to JSON
604
+ *
605
+ * From RRDSET extract content necessary to write JSON output.
606
+ *
607
+ * @param st netdata chart structure
608
+ * @param data structure with necessary data and to build expected result.
609
+ *
610
+ * @return I returns 1 when content was used and 0 otherwise.
611
+ */
612
+static int prometheus_rrdset_to_json(RRDSET *st, void *data)
613
+{
614
+ struct host_variables_callback_options *opts = data;
615
+
616
+ if (likely(can_send_rrdset(opts->instance, st, opts->pattern))) {
617
+ PROMETHEUS_OUTPUT_OPTIONS output_options = opts->output_options;
618
+ BUFFER *wb = opts->wb;
619
+ const char *prefix = opts->prefix;
620
+
621
+ BUFFER *plabels_buffer = opts->plabels_buffer;
622
+ const char *plabels_prefix = opts->instance->config.label_prefix;
623
+
624
+ STRING *prometheus = opts->prometheus;
625
+
626
+ char chart[PROMETHEUS_ELEMENT_MAX + 1];
627
+ char context[PROMETHEUS_ELEMENT_MAX + 1];
628
+ char family[PROMETHEUS_ELEMENT_MAX + 1];
629
+ char units[PROMETHEUS_ELEMENT_MAX + 1] = "";
630
+
631
+ prometheus_label_copy(chart,
632
+ (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ?
633
+ rrdset_name(st) : rrdset_id(st), PROMETHEUS_ELEMENT_MAX);
634
+ prometheus_label_copy(family, rrdset_family(st), PROMETHEUS_ELEMENT_MAX);
635
+ prometheus_name_copy(context, rrdset_context(st), PROMETHEUS_ELEMENT_MAX);
636
+
637
+ int as_collected = (EXPORTING_OPTIONS_DATA_SOURCE(opts->exporting_options)
638
+ == EXPORTING_SOURCE_DATA_AS_COLLECTED);
639
+ int homogeneous = 1;
640
+ int prometheus_collector = 0;
641
+ RRDSET_FLAGS flags = rrdset_flag_get(st);
642
+ if (as_collected) {
643
+ if (flags & RRDSET_FLAG_HOMOGENEOUS_CHECK)
644
+ rrdset_update_heterogeneous_flag(st);
645
+
646
+ if (flags & RRDSET_FLAG_HETEROGENEOUS)
647
+ homogeneous = 0;
648
+
649
+ if (st->module_name == prometheus)
650
+ prometheus_collector = 1;
651
+ }
652
+ else {
653
+ if (EXPORTING_OPTIONS_DATA_SOURCE(opts->exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE &&
654
+ !(output_options & PROMETHEUS_OUTPUT_HIDEUNITS))
655
+ prometheus_units_copy(units,
656
+ rrdset_units(st),
657
+ PROMETHEUS_ELEMENT_MAX,
658
+ output_options & PROMETHEUS_OUTPUT_OLDUNITS);
659
+ }
660
+
661
+ // for each dimension
662
+ RRDDIM *rd;
663
+ rrddim_foreach_read(rd, st) {
664
+
665
+ if (rd->collector.counter && !rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) {
666
+ char dimension[PROMETHEUS_ELEMENT_MAX + 1];
667
+ char *suffix = "";
668
+
669
+ struct gen_parameters p;
670
+ p.prefix = prefix;
671
+ p.labels_prefix = plabels_prefix;
672
+ p.context = context;
673
+ p.suffix = suffix;
674
+ p.chart = chart;
675
+ p.dimension = dimension;
676
+ p.family = family;
677
+ p.labels = (char *)opts->labels;
678
+ p.output_options = output_options;
679
+ p.st = st;
680
+ p.rd = rd;
681
+
682
+ if (as_collected) {
683
+ // we need as-collected / raw data
684
+
685
+ if (unlikely(rd->collector.last_collected_time.tv_sec < opts->instance->after))
686
+ continue;
687
+
688
+ p.type = "gauge";
689
+ p.relation = "gives";
690
+ if (rd->algorithm == RRD_ALGORITHM_INCREMENTAL ||
691
+ rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
692
+ p.type = "counter";
693
+ p.relation = "delta gives";
694
+ if (!prometheus_collector)
695
+ p.suffix = "_total";
696
+ }
697
+
698
+ if (opts->output_options & PROMETHEUS_OUTPUT_HELP_TYPE) {
699
+ generate_as_collected_prom_help(wb, prefix, context, units, suffix, st);
700
+ generate_as_collected_prom_type(wb, prefix, context, units, p.suffix, p.type);
701
+ opts->output_options &= ~PROMETHEUS_OUTPUT_HELP_TYPE;
702
+ }
703
+
704
+ if (homogeneous) {
705
+ // all the dimensions of the chart, has the same algorithm, multiplier and divisor
706
+ // we add all dimensions as labels
707
+
708
+ prometheus_label_copy(
709
+ dimension,
710
+ (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
711
+ PROMETHEUS_ELEMENT_MAX);
712
+ }
713
+ else {
714
+ // the dimensions of the chart, do not have the same algorithm, multiplier or divisor
715
+ // we create a metric per dimension
716
+
717
+ prometheus_name_copy(
718
+ dimension,
719
+ (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
720
+ PROMETHEUS_ELEMENT_MAX);
721
+ }
722
+ generate_as_collected_from_metric(wb, &p, homogeneous, prometheus_collector, st->rrdlabels);
723
+ }
724
+ else {
725
+ // we need average or sum of the data
726
+
727
+ time_t last_time = opts->instance->before;
728
+ NETDATA_DOUBLE value = exporting_calculate_value_from_stored_data(opts->instance, rd, &last_time);
729
+
730
+ if (!isnan(value) && !isinf(value)) {
731
+ if (EXPORTING_OPTIONS_DATA_SOURCE(opts->exporting_options)
732
+ == EXPORTING_SOURCE_DATA_AVERAGE)
733
+ suffix = "_average";
734
+ else if (EXPORTING_OPTIONS_DATA_SOURCE(opts->exporting_options)
735
+ == EXPORTING_SOURCE_DATA_SUM)
736
+ suffix = "_sum";
737
+
738
+ prometheus_label_copy(
739
+ dimension,
740
+ (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
741
+ PROMETHEUS_ELEMENT_MAX);
742
+
743
+ if (opts->output_options & PROMETHEUS_OUTPUT_HELP_TYPE) {
744
+ generate_as_collected_prom_help(wb, prefix, context, units, suffix, st);
745
+ generate_as_collected_prom_type(wb, prefix, context, units, p.suffix, "gauge");
746
+ opts->output_options &= ~PROMETHEUS_OUTPUT_HELP_TYPE;
747
+ }
748
+
749
+ buffer_flush(plabels_buffer);
750
+ buffer_sprintf(plabels_buffer,
751
+ "%1$schart=\"%2$s\",%1$sdimension=\"%3$s\",%1$sfamily=\"%4$s\"",
752
+ plabels_prefix,
753
+ chart,
754
+ dimension,
755
+ family);
756
+ rrdlabels_walkthrough_read(st->rrdlabels,
757
+ format_prometheus_chart_label_callback,
758
+ plabels_buffer);
759
+
760
+ if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
761
+ buffer_sprintf(wb,
762
+ "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT " %llu\n",
763
+ prefix,
764
+ context,
765
+ units,
766
+ suffix,
767
+ buffer_tostring(plabels_buffer),
768
+ opts->labels,
769
+ value,
770
+ last_time * MSEC_PER_SEC);
771
+ else
772
+ buffer_sprintf(wb, "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT "\n",
773
+ prefix,
774
+ context,
775
+ units,
776
+ suffix,
777
+ buffer_tostring(plabels_buffer),
778
+ opts->labels,
779
+ value);
780
+ }
781
+ }
782
+ }
783
+ }
784
+ rrddim_foreach_done(rd);
785
+
786
+ return 1;
787
+ }
788
+
789
+ return 0;
790
+}
791
+
792
+/**
793
+ * RRDCONTEXT callback
794
+ *
795
+ * Callback used to parse dictionary
796
+ *
797
+ * @param item the dictionary structure
798
+ * @param value unused element
799
+ * @param data structure used to store data.
800
+ *
801
+ * @return It always returns HTTP_RESP_OK
802
+ */
803
+static inline int prometheus_rrdcontext_callback(const DICTIONARY_ITEM *item, void *value, void *data)
804
+{
805
+ const char *context_name = dictionary_acquired_item_name(item);
806
+ struct host_variables_callback_options *opts = data;
807
+ (void)value;
808
+
809
+ opts->output_options |= PROMETHEUS_OUTPUT_HELP_TYPE;
810
+ (void)rrdcontext_foreach_instance_with_rrdset_in_context(opts->host, context_name, prometheus_rrdset_to_json, data);
811
+
812
+ return HTTP_RESP_OK;
813
+}
814
+
815
/**
816
* Write metrics in Prometheus format to a buffer.
817
*
@@ -658,219 +868,41 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
868
if (instance->config.options & EXPORTING_OPTION_SEND_AUTOMATIC_LABELS)
869
prometheus_print_os_info(wb, host, output_options);
870
661
- // send custom variables set for the host
662
- if (output_options & PROMETHEUS_OUTPUT_VARIABLES) {
663
-
664
- struct host_variables_callback_options opts = {
665
- .host = host,
666
- .wb = wb,
667
- .labels = (labels[0] == ',') ? &labels[1] : labels,
668
- .exporting_options = exporting_options,
669
- .output_options = output_options,
670
- .prefix = prefix,
671
- .now = now_realtime_sec(),
672
- .host_header_printed = 0
673
- };
674
-
675
- rrdvar_walkthrough_read(host->rrdvars, print_host_variables_callback, &opts);
676
- }
677
-
678
- // for each chart
679
- RRDSET *st;
871
872
BUFFER *plabels_buffer = buffer_create(0, NULL);
682
- const char *plabels_prefix = instance->config.label_prefix;
683
-
684
- STRING *prometheus = string_strdupz("prometheus");
685
- rrdset_foreach_read(st, host) {
686
-
687
- if (likely(can_send_rrdset(instance, st, filter))) {
688
- char chart[PROMETHEUS_ELEMENT_MAX + 1];
689
- char context[PROMETHEUS_ELEMENT_MAX + 1];
690
- char family[PROMETHEUS_ELEMENT_MAX + 1];
691
- char units[PROMETHEUS_ELEMENT_MAX + 1] = "";
692
-
693
- prometheus_label_copy(chart, (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? rrdset_name(st) : rrdset_id(st), PROMETHEUS_ELEMENT_MAX);
694
- prometheus_label_copy(family, rrdset_family(st), PROMETHEUS_ELEMENT_MAX);
695
- prometheus_name_copy(context, rrdset_context(st), PROMETHEUS_ELEMENT_MAX);
696
-
697
- int as_collected = (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AS_COLLECTED);
698
- int homogeneous = 1;
699
- int prometheus_collector = 0;
700
- RRDSET_FLAGS flags = rrdset_flag_get(st);
701
- if (as_collected) {
702
- if (flags & RRDSET_FLAG_HOMOGENEOUS_CHECK)
703
- rrdset_update_heterogeneous_flag(st);
704
-
705
- if (flags & RRDSET_FLAG_HETEROGENEOUS)
706
- homogeneous = 0;
707
-
708
- if (st->module_name == prometheus)
709
- prometheus_collector = 1;
710
- }
711
- else {
712
- if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE &&
713
- !(output_options & PROMETHEUS_OUTPUT_HIDEUNITS))
714
- prometheus_units_copy(
715
- units, rrdset_units(st), PROMETHEUS_ELEMENT_MAX, output_options & PROMETHEUS_OUTPUT_OLDUNITS);
716
- }
717
-
718
- if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
719
- buffer_sprintf(
720
- wb,
721
- "\n# COMMENT %s chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n",
722
- (homogeneous) ? "homogeneous" : "heterogeneous",
723
- (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? rrdset_name(st) : rrdset_id(st),
724
- rrdset_context(st),
725
- rrdset_family(st),
726
- rrdset_units(st));
727
-
728
- // for each dimension
729
- RRDDIM *rd;
730
- rrddim_foreach_read(rd, st) {
731
- if (rd->collector.counter && !rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) {
732
- char dimension[PROMETHEUS_ELEMENT_MAX + 1];
733
- char *suffix = "";
734
-
735
- if (as_collected) {
736
- // we need as-collected / raw data
737
-
738
- struct gen_parameters p;
739
- p.prefix = prefix;
740
- p.labels_prefix = instance->config.label_prefix;
741
- p.context = context;
742
- p.suffix = suffix;
743
- p.chart = chart;
744
- p.dimension = dimension;
745
- p.family = family;
746
- p.labels = labels;
747
- p.output_options = output_options;
748
- p.st = st;
749
- p.rd = rd;
750
-
751
- if (unlikely(rd->collector.last_collected_time.tv_sec < instance->after))
752
- continue;
753
-
754
- p.type = "gauge";
755
- p.relation = "gives";
756
- if (rd->algorithm == RRD_ALGORITHM_INCREMENTAL ||
757
- rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
758
- p.type = "counter";
759
- p.relation = "delta gives";
760
- if (!prometheus_collector)
761
- p.suffix = "_total";
762
- }
763
-
764
- if (homogeneous) {
765
- // all the dimensions of the chart, has the same algorithm, multiplier and divisor
766
- // we add all dimensions as labels
767
-
768
- prometheus_label_copy(
769
- dimension,
770
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
771
- PROMETHEUS_ELEMENT_MAX);
772
-
773
- if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
774
- generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
775
-
776
- if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
777
- buffer_sprintf(wb, "# TYPE %s_%s%s %s\n", prefix, context, suffix, p.type);
778
-
779
- generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector, st->rrdlabels);
780
- }
781
- else {
782
- // the dimensions of the chart, do not have the same algorithm, multiplier or divisor
783
- // we create a metric per dimension
784
-
785
- prometheus_name_copy(
786
- dimension,
787
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
788
- PROMETHEUS_ELEMENT_MAX);
873
790
- if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
791
- generate_as_collected_prom_help(wb, &p, homogeneous, prometheus_collector);
874
+ struct host_variables_callback_options opts = {
875
+ .host = host,
876
+ .wb = wb,
877
+ .plabels_buffer = plabels_buffer,
878
+ .labels = (labels[0] == ',') ? &labels[1] : labels,
879
+ .exporting_options = exporting_options,
880
+ .output_options = output_options,
881
+ .prefix = prefix,
882
+ .now = now_realtime_sec(),
883
+ .host_header_printed = 0,
884
+ .pattern = filter,
885
+ .instance = instance,
886
+ .prometheus = string_strdupz("prometheus")
887
+ };
888
793
- if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
794
- buffer_sprintf(
795
- wb, "# TYPE %s_%s_%s%s %s\n", prefix, context, dimension, suffix, p.type);
889
+ // send custom variables set for the host
890
+ if (output_options & PROMETHEUS_OUTPUT_VARIABLES) {
891
+ rrdvar_walkthrough_read(host->rrdvars, print_host_variables_callback, &opts);
892
+ }
893
797
- generate_as_collected_prom_metric(wb, &p, homogeneous, prometheus_collector, st->rrdlabels);
798
- }
799
- }
800
- else {
801
- // we need average or sum of the data
802
-
803
- time_t first_time = instance->after;
804
- time_t last_time = instance->before;
805
- NETDATA_DOUBLE value = exporting_calculate_value_from_stored_data(instance, rd, &last_time);
806
-
807
- if (!isnan(value) && !isinf(value)) {
808
- if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE)
809
- suffix = "_average";
810
- else if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_SUM)
811
- suffix = "_sum";
812
-
813
- prometheus_label_copy(
814
- dimension,
815
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
816
- PROMETHEUS_ELEMENT_MAX);
817
-
818
- buffer_flush(plabels_buffer);
819
- buffer_sprintf(plabels_buffer, "%1$schart=\"%2$s\",%1$sdimension=\"%3$s\",%1$sfamily=\"%4$s\"", plabels_prefix, chart, dimension, family);
820
- rrdlabels_walkthrough_read(st->rrdlabels, format_prometheus_chart_label_callback, plabels_buffer);
821
-
822
- if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
823
- buffer_sprintf(
824
- wb,
825
- "# COMMENT %s_%s%s%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n",
826
- prefix,
827
- context,
828
- units,
829
- suffix,
830
- (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
831
- rrdset_units(st),
832
- (unsigned long long)first_time,
833
- (unsigned long long)last_time);
834
-
835
- if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
836
- buffer_sprintf(wb, "# TYPE %s_%s%s%s gauge\n", prefix, context, units, suffix);
837
-
838
- if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
839
- buffer_sprintf(
840
- wb,
841
- "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT
842
- " %llu\n",
843
- prefix,
844
- context,
845
- units,
846
- suffix,
847
- buffer_tostring(plabels_buffer),
848
- labels,
849
- value,
850
- last_time * MSEC_PER_SEC);
851
- else
852
- buffer_sprintf(
853
- wb,
854
- "%s_%s%s%s{%s%s} " NETDATA_DOUBLE_FORMAT
855
- "\n",
856
- prefix,
857
- context,
858
- units,
859
- suffix,
860
- buffer_tostring(plabels_buffer),
861
- labels,
862
- value);
863
- }
864
- }
865
- }
866
- }
867
- rrddim_foreach_done(rd);
868
- }
894
+ // for each context
895
+ if (!host->rrdctx.contexts) {
896
+ netdata_log_error("%s(): request for host '%s' that does not have rrdcontexts initialized.", __FUNCTION__, rrdhost_hostname(host));
897
+ goto allmetrics_cleanup;
898
}
870
- rrdset_foreach_done(st);
899
872
- buffer_free(plabels_buffer);
900
+ dictionary_walkthrough_read(host->rrdctx.contexts, prometheus_rrdcontext_callback, &opts);
901
+
902
+allmetrics_cleanup:
903
simple_pattern_free(filter);
904
+ buffer_free(plabels_buffer);
905
+ string_freez(opts.prometheus);
906
}
907
908
/**
@@ -888,11 +920,8 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
920
static inline time_t prometheus_preparation(
921
struct instance *instance,
922
RRDHOST *host,
891
- BUFFER *wb,
892
- EXPORTING_OPTIONS exporting_options,
923
const char *server,
894
- time_t now,
895
- PROMETHEUS_OUTPUT_OPTIONS output_options)
924
+ time_t now)
925
{
926
#ifndef UNIT_TESTING
927
analytics_log_prometheus();
@@ -902,10 +931,8 @@ static inline time_t prometheus_preparation(
931
932
time_t after = prometheus_server_last_access(server, host, now);
933
905
- int first_seen = 0;
934
if (!after) {
935
after = now - instance->config.update_every;
908
- first_seen = 1;
936
}
937
938
if (after > now) {
@@ -913,30 +940,6 @@ static inline time_t prometheus_preparation(
940
after = now - instance->config.update_every;
941
}
942
916
- if (output_options & PROMETHEUS_OUTPUT_HELP) {
917
- char *mode;
918
- if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AS_COLLECTED)
919
- mode = "as collected";
920
- else if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_AVERAGE)
921
- mode = "average";
922
- else if (EXPORTING_OPTIONS_DATA_SOURCE(exporting_options) == EXPORTING_SOURCE_DATA_SUM)
923
- mode = "sum";
924
- else
925
- mode = "unknown";
926
-
927
- buffer_sprintf(
928
- wb,
929
- "# COMMENT netdata \"%s\" to %sprometheus \"%s\", source \"%s\", last seen %lu %s, time range %lu to %lu\n\n",
930
- rrdhost_hostname(host),
931
- (first_seen) ? "FIRST SEEN " : "",
932
- server,
933
- mode,
934
- (unsigned long)((first_seen) ? 0 : (now - after)),
935
- (first_seen) ? "never" : "seconds ago",
936
- (unsigned long)after,
937
- (unsigned long)now);
938
- }
939
-
943
return after;
944
}
945
@@ -969,11 +972,8 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(
972
prometheus_exporter_instance->after = prometheus_preparation(
973
prometheus_exporter_instance,
974
host,
972
- wb,
973
- exporting_options,
975
server,
975
- prometheus_exporter_instance->before,
976
- output_options);
976
+ prometheus_exporter_instance->before);
977
978
rrd_stats_api_v1_charts_allmetrics_prometheus(
979
prometheus_exporter_instance, host, filter_string, wb, prefix, exporting_options, 0, output_options);
@@ -1008,11 +1008,8 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(
1008
prometheus_exporter_instance->after = prometheus_preparation(
1009
prometheus_exporter_instance,
1010
host,
1011
- wb,
1012
- exporting_options,
1011
server,
1014
- prometheus_exporter_instance->before,
1015
- output_options);
1012
+ prometheus_exporter_instance->before);
1013
1014
dfe_start_reentrant(rrdhost_root_index, host)
1015
{
src/exporting/prometheus/prometheus.h
+3
-4
@@ -11,13 +11,12 @@
11
12
typedef enum prometheus_output_flags {
13
PROMETHEUS_OUTPUT_NONE = 0,
14
- PROMETHEUS_OUTPUT_HELP = (1 << 0),
15
- PROMETHEUS_OUTPUT_TYPES = (1 << 1),
14
+ PROMETHEUS_OUTPUT_HELP_TYPE = (1 << 1),
15
PROMETHEUS_OUTPUT_NAMES = (1 << 2),
16
PROMETHEUS_OUTPUT_TIMESTAMPS = (1 << 3),
17
PROMETHEUS_OUTPUT_VARIABLES = (1 << 4),
19
- PROMETHEUS_OUTPUT_OLDUNITS = (1 << 5),
20
- PROMETHEUS_OUTPUT_HIDEUNITS = (1 << 6)
18
+ PROMETHEUS_OUTPUT_OLDUNITS = (1 << 5),
19
+ PROMETHEUS_OUTPUT_HIDEUNITS = (1 << 6)
20
} PROMETHEUS_OUTPUT_OPTIONS;
21
22
void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(
src/web/api/exporters/allmetrics.c
+2
-3
@@ -6,8 +6,6 @@ struct prometheus_output_options {
6
char *name;
7
PROMETHEUS_OUTPUT_OPTIONS flag;
8
} prometheus_output_flags_root[] = {
9
- { "help", PROMETHEUS_OUTPUT_HELP },
10
- { "types", PROMETHEUS_OUTPUT_TYPES },
9
{ "names", PROMETHEUS_OUTPUT_NAMES },
10
{ "timestamps", PROMETHEUS_OUTPUT_TIMESTAMPS },
11
{ "variables", PROMETHEUS_OUTPUT_VARIABLES },
@@ -76,8 +74,9 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client
74
if(!strcmp(name, prometheus_output_flags_root[i].name)) {
75
if(!strcmp(value, "yes") || !strcmp(value, "1") || !strcmp(value, "true"))
76
prometheus_output_options |= prometheus_output_flags_root[i].flag;
79
- else
77
+ else {
78
prometheus_output_options &= ~prometheus_output_flags_root[i].flag;
79
+ }
80
81
break;
82
}
src/web/api/netdata-swagger.json
-28
@@ -901,34 +901,6 @@
901
"default": "no"
902
}
903
},
904
- {
905
- "name": "help",
906
- "in": "query",
907
- "description": "Enable or disable HELP lines in prometheus output.\n",
908
- "required": false,
909
- "schema": {
910
- "type": "string",
911
- "enum": [
912
- "yes",
913
- "no"
914
- ],
915
- "default": "no"
916
- }
917
- },
918
- {
919
- "name": "types",
920
- "in": "query",
921
- "description": "Enable or disable TYPE lines in prometheus output.\n",
922
- "required": false,
923
- "schema": {
924
- "type": "string",
925
- "enum": [
926
- "yes",
927
- "no"
928
- ],
929
- "default": "no"
930
- }
931
- },
904
{
905
"name": "timestamps",
906
"in": "query",
src/web/api/netdata-swagger.yaml
-22
@@ -554,28 +554,6 @@ paths:
554
- yes
555
- no
556
default: no
557
- - name: help
558
- in: query
559
- description: |
560
- Enable or disable HELP lines in prometheus output.
561
- required: false
562
- schema:
563
- type: string
564
- enum:
565
- - yes
566
- - no
567
- default: no
568
- - name: types
569
- in: query
570
- description: |
571
- Enable or disable TYPE lines in prometheus output.
572
- required: false
573
- schema:
574
- type: string
575
- enum:
576
- - yes
577
- - no
578
- default: no
557
- name: timestamps
558
in: query
559
description: |