summaryrefslogtreecommitdiffstats
path: root/backends/prometheus/backend_prometheus.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--backends/prometheus/backend_prometheus.c (renamed from src/backend_prometheus.c)177
1 files changed, 132 insertions, 45 deletions
diff --git a/src/backend_prometheus.c b/backends/prometheus/backend_prometheus.c
index bfcda9297..223b3f9f0 100644
--- a/src/backend_prometheus.c
+++ b/backends/prometheus/backend_prometheus.c
@@ -1,4 +1,7 @@
-#include "common.h"
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#define BACKENDS_INTERNALS
+#include "backend_prometheus.h"
// ----------------------------------------------------------------------------
// PROMETHEUS
@@ -109,8 +112,77 @@ static inline char *prometheus_units_copy(char *d, const char *s, size_t usable)
#define PROMETHEUS_ELEMENT_MAX 256
#define PROMETHEUS_LABELS_MAX 1024
+#define PROMETHEUS_VARIABLE_MAX 256
+
+struct host_variables_callback_options {
+ RRDHOST *host;
+ BUFFER *wb;
+ BACKEND_OPTIONS backend_options;
+ PROMETHEUS_OUTPUT_OPTIONS output_options;
+ const char *prefix;
+ const char *labels;
+ time_t now;
+ int host_header_printed;
+ char name[PROMETHEUS_VARIABLE_MAX+1];
+};
+
+static int print_host_variables(RRDVAR *rv, void *data) {
+ struct host_variables_callback_options *opts = data;
+
+ if(rv->options & (RRDVAR_OPTION_CUSTOM_HOST_VAR|RRDVAR_OPTION_CUSTOM_CHART_VAR)) {
+ if(!opts->host_header_printed) {
+ opts->host_header_printed = 1;
+
+ if(opts->output_options & PROMETHEUS_OUTPUT_HELP) {
+ buffer_sprintf(opts->wb, "\n# COMMENT global host and chart variables\n");
+ }
+ }
+
+ calculated_number value = rrdvar2number(rv);
+ if(isnan(value) || isinf(value)) {
+ if(opts->output_options & PROMETHEUS_OUTPUT_HELP)
+ buffer_sprintf(opts->wb, "# COMMENT variable \"%s\" is %s. Skipped.\n", rv->name, (isnan(value))?"NAN":"INF");
+
+ return 0;
+ }
+
+ char *label_pre = "";
+ char *label_post = "";
+ if(opts->labels && *opts->labels) {
+ label_pre = "{";
+ label_post = "}";
+ }
-static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, const char *prefix, uint32_t options, time_t after, time_t before, int allhosts, int help, int types, int names, int timestamps) {
+ prometheus_name_copy(opts->name, rv->name, sizeof(opts->name));
+
+ if(opts->output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
+ buffer_sprintf(opts->wb
+ , "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT " %llu\n"
+ , opts->prefix
+ , opts->name
+ , label_pre
+ , opts->labels
+ , label_post
+ , value
+ , ((rv->last_updated) ? rv->last_updated : opts->now) * 1000ULL
+ );
+ else
+ buffer_sprintf(opts->wb, "%s_%s%s%s%s " CALCULATED_NUMBER_FORMAT "\n"
+ , opts->prefix
+ , opts->name
+ , label_pre
+ , opts->labels
+ , label_post
+ , value
+ );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, const char *prefix, BACKEND_OPTIONS backend_options, time_t after, time_t before, int allhosts, PROMETHEUS_OUTPUT_OPTIONS output_options) {
rrdhost_rdlock(host);
char hostname[PROMETHEUS_ELEMENT_MAX + 1];
@@ -118,13 +190,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
char labels[PROMETHEUS_LABELS_MAX + 1] = "";
if(allhosts) {
- if(timestamps)
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS);
else
buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version);
if(host->tags && *(host->tags)) {
- if(timestamps) {
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) {
buffer_sprintf(wb, "netdata_host_tags_info{instance=\"%s\",%s} 1 %llu\n", hostname, host->tags, now_realtime_usec() / USEC_PER_MS);
// deprecated, exists only for compatibility with older queries
@@ -142,13 +214,13 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
snprintfz(labels, PROMETHEUS_LABELS_MAX, ",instance=\"%s\"", hostname);
}
else {
- if(timestamps)
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1 %llu\n", hostname, host->program_name, host->program_version, now_realtime_usec() / USEC_PER_MS);
else
buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"} 1\n", hostname, host->program_name, host->program_version);
if(host->tags && *(host->tags)) {
- if(timestamps) {
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) {
buffer_sprintf(wb, "netdata_host_tags_info{%s} 1 %llu\n", host->tags, now_realtime_usec() / USEC_PER_MS);
// deprecated, exists only for compatibility with older queries
@@ -163,6 +235,21 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
}
}
+ // send custom variables set for the host
+ if(output_options & PROMETHEUS_OUTPUT_VARIABLES){
+ struct host_variables_callback_options opts = {
+ .host = host,
+ .wb = wb,
+ .labels = (labels[0] == ',')?&labels[1]:labels,
+ .backend_options = backend_options,
+ .output_options = output_options,
+ .prefix = prefix,
+ .now = now_realtime_sec(),
+ .host_header_printed = 0
+ };
+ foreach_host_variable_callback(host, print_host_variables, &opts);
+ }
+
// for each chart
RRDSET *st;
rrdset_foreach_read(st, host) {
@@ -171,14 +258,14 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
char family[PROMETHEUS_ELEMENT_MAX + 1];
char units[PROMETHEUS_ELEMENT_MAX + 1] = "";
- prometheus_label_copy(chart, (names && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX);
+ prometheus_label_copy(chart, (output_options & PROMETHEUS_OUTPUT_NAMES && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX);
prometheus_label_copy(family, st->family, PROMETHEUS_ELEMENT_MAX);
prometheus_name_copy(context, st->context, PROMETHEUS_ELEMENT_MAX);
- if(likely(backends_can_send_rrdset(options, st))) {
+ if(likely(backends_can_send_rrdset(backend_options, st))) {
rrdset_rdlock(st);
- int as_collected = ((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED);
+ int as_collected = (BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED);
int homogeneus = 1;
if(as_collected) {
if(rrdset_flag_check(st, RRDSET_FLAG_HOMEGENEOUS_CHECK))
@@ -188,14 +275,14 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
homogeneus = 0;
}
else {
- if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE)
+ if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE)
prometheus_units_copy(units, st->units, PROMETHEUS_ELEMENT_MAX);
}
- if(unlikely(help))
+ if(unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
buffer_sprintf(wb, "\n# COMMENT %s chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n"
, (homogeneus)?"homogeneus":"heterogeneous"
- , (names && st->name) ? st->name : st->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id
, st->context
, st->family
, st->units
@@ -223,18 +310,18 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
// all the dimensions of the chart, has the same algorithm, multiplier and divisor
// we add all dimensions as labels
- prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
+ prometheus_label_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
- if(unlikely(help))
+ 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
- , (names && st->name) ? st->name : st->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id
, st->context
, st->family
- , (names && rd->name) ? rd->name : rd->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id
, rd->multiplier
, rd->divisor
, h
@@ -242,7 +329,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
, t
);
- if(unlikely(types))
+ if(unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s %s\n"
, prefix
, context
@@ -250,7 +337,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
, t
);
- if(timestamps)
+ 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
@@ -280,19 +367,19 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
// the dimensions of the chart, do not have the same algorithm, multiplier or divisor
// we create a metric per dimension
- prometheus_name_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
+ prometheus_name_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
- if(unlikely(help))
+ 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
- , (names && st->name) ? st->name : st->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && st->name) ? st->name : st->id
, st->context
, st->family
- , (names && rd->name) ? rd->name : rd->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id
, rd->multiplier
, rd->divisor
, h
@@ -300,7 +387,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
, t
);
- if(unlikely(types))
+ if(unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
buffer_sprintf(wb, "# COMMENT TYPE %s_%s_%s%s %s\n"
, prefix
, context
@@ -309,7 +396,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
, t
);
- if(timestamps)
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
buffer_sprintf(wb
, "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n"
, prefix
@@ -340,30 +427,30 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
// we need average or sum of the data
time_t first_t = after, last_t = before;
- calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
+ calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t);
if(!isnan(value) && !isinf(value)) {
- if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE)
+ if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE)
suffix = "_average";
- else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_SUM)
+ else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM)
suffix = "_sum";
- prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
+ prometheus_label_copy(dimension, (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
- if (unlikely(help))
+ if (unlikely(output_options & PROMETHEUS_OUTPUT_HELP))
buffer_sprintf(wb, "# COMMENT %s_%s%s%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n"
, prefix
, context
, units
, suffix
- , (names && rd->name) ? rd->name : rd->id
+ , (output_options & PROMETHEUS_OUTPUT_NAMES && rd->name) ? rd->name : rd->id
, st->units
, (unsigned long long)first_t
, (unsigned long long)last_t
);
- if (unlikely(types))
+ if (unlikely(output_options & PROMETHEUS_OUTPUT_TYPES))
buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s%s gauge\n"
, prefix
, context
@@ -371,7 +458,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
, suffix
);
- if(timestamps)
+ if(output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
buffer_sprintf(wb, "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n"
, prefix
, context
@@ -408,32 +495,32 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
rrdhost_unlock(host);
}
-static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t options, const char *server, time_t now, int help) {
+static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, BACKEND_OPTIONS backend_options, const char *server, time_t now, PROMETHEUS_OUTPUT_OPTIONS output_options) {
if(!server || !*server) server = "default";
time_t after = prometheus_server_last_access(server, host, now);
int first_seen = 0;
if(!after) {
- after = now - backend_update_every;
+ after = now - global_backend_update_every;
first_seen = 1;
}
if(after > now) {
// oops! this should never happen
- after = now - backend_update_every;
+ after = now - global_backend_update_every;
}
- if(help) {
+ if(output_options & PROMETHEUS_OUTPUT_HELP) {
int show_range = 1;
char *mode;
- if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED) {
+ if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED) {
mode = "as collected";
show_range = 0;
}
- else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE)
+ else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_AVERAGE)
mode = "average";
- else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_SUM)
+ else if(BACKEND_OPTIONS_DATA_SOURCE(backend_options) == BACKEND_SOURCE_DATA_SUM)
mode = "sum";
else
mode = "unknown";
@@ -456,24 +543,24 @@ static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t
return after;
}
-void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names, int timestamps) {
+void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, PROMETHEUS_OUTPUT_OPTIONS output_options) {
time_t before = now_realtime_sec();
// we start at the point we had stopped before
- time_t after = prometheus_preparation(host, wb, options, server, before, help);
+ time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options);
- rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, options, after, before, 0, help, types, names, timestamps);
+ rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 0, output_options);
}
-void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names, int timestamps) {
+void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, BACKEND_OPTIONS backend_options, PROMETHEUS_OUTPUT_OPTIONS output_options) {
time_t before = now_realtime_sec();
// we start at the point we had stopped before
- time_t after = prometheus_preparation(host, wb, options, server, before, help);
+ time_t after = prometheus_preparation(host, wb, backend_options, server, before, output_options);
rrd_rdlock();
rrdhost_foreach_read(host) {
- rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, options, after, before, 1, help, types, names, timestamps);
+ rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, backend_options, after, before, 1, output_options);
}
rrd_unlock();
}