summaryrefslogtreecommitdiffstats
path: root/exporting/prometheus/remote_write/remote_write.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 12:08:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 12:08:18 +0000
commit5da14042f70711ea5cf66e034699730335462f66 (patch)
tree0f6354ccac934ed87a2d555f45be4c831cf92f4a /exporting/prometheus/remote_write/remote_write.c
parentReleasing debian version 1.44.3-2. (diff)
downloadnetdata-5da14042f70711ea5cf66e034699730335462f66.tar.xz
netdata-5da14042f70711ea5cf66e034699730335462f66.zip
Merging upstream version 1.45.3+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'exporting/prometheus/remote_write/remote_write.c')
-rw-r--r--exporting/prometheus/remote_write/remote_write.c405
1 files changed, 0 insertions, 405 deletions
diff --git a/exporting/prometheus/remote_write/remote_write.c b/exporting/prometheus/remote_write/remote_write.c
deleted file mode 100644
index ed431c9dc..000000000
--- a/exporting/prometheus/remote_write/remote_write.c
+++ /dev/null
@@ -1,405 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "remote_write.h"
-
-static int as_collected;
-static int homogeneous;
-char context[PROMETHEUS_ELEMENT_MAX + 1];
-char chart[PROMETHEUS_ELEMENT_MAX + 1];
-char family[PROMETHEUS_ELEMENT_MAX + 1];
-char units[PROMETHEUS_ELEMENT_MAX + 1] = "";
-
-/**
- * Prepare HTTP header
- *
- * @param instance an instance data structure.
- */
-void prometheus_remote_write_prepare_header(struct instance *instance)
-{
- struct prometheus_remote_write_specific_config *connector_specific_config =
- instance->config.connector_specific_config;
- struct simple_connector_data *simple_connector_data = instance->connector_specific_data;
-
- buffer_sprintf(
- simple_connector_data->last_buffer->header,
- "POST %s HTTP/1.1\r\n"
- "Host: %s\r\n"
- "Accept: */*\r\n"
- "%s"
- "Content-Encoding: snappy\r\n"
- "Content-Type: application/x-protobuf\r\n"
- "X-Prometheus-Remote-Write-Version: 0.1.0\r\n"
- "Content-Length: %zu\r\n"
- "\r\n",
- connector_specific_config->remote_write_path,
- simple_connector_data->connected_to,
- simple_connector_data->auth_string ? simple_connector_data->auth_string : "",
- buffer_strlen(simple_connector_data->last_buffer->buffer));
-}
-
-/**
- * Process a response received after Prometheus remote write connector had sent data
- *
- * @param buffer a response from a remote service.
- * @param instance an instance data structure.
- * @return Returns 0 on success, 1 on failure.
- */
-int process_prometheus_remote_write_response(BUFFER *buffer, struct instance *instance)
-{
- if (unlikely(!buffer))
- return 1;
-
- const char *s = buffer_tostring(buffer);
- int len = buffer_strlen(buffer);
-
- // do nothing with HTTP responses 200 or 204
-
- while (!isspace(*s) && len) {
- s++;
- len--;
- }
- s++;
- len--;
-
- if (likely(len > 4 && (!strncmp(s, "200 ", 4) || !strncmp(s, "204 ", 4))))
- return 0;
- else
- return exporting_discard_response(buffer, instance);
-}
-
-/**
- * Release specific data allocated.
- *
- * @param instance an instance data structure.
- */
-void clean_prometheus_remote_write(struct instance *instance)
-{
- struct simple_connector_data *simple_connector_data = instance->connector_specific_data;
- freez(simple_connector_data->connector_specific_data);
-
- struct prometheus_remote_write_specific_config *connector_specific_config =
- instance->config.connector_specific_config;
- freez(connector_specific_config->remote_write_path);
-}
-
-/**
- * Initialize Prometheus Remote Write connector instance
- *
- * @param instance an instance data structure.
- * @return Returns 0 on success, 1 on failure.
- */
-int init_prometheus_remote_write_instance(struct instance *instance)
-{
- instance->worker = simple_connector_worker;
-
- instance->start_batch_formatting = NULL;
- instance->start_host_formatting = format_host_prometheus_remote_write;
- instance->start_chart_formatting = format_chart_prometheus_remote_write;
- instance->metric_formatting = format_dimension_prometheus_remote_write;
- instance->end_chart_formatting = NULL;
- instance->variables_formatting = format_variables_prometheus_remote_write;
- instance->end_host_formatting = NULL;
- instance->end_batch_formatting = format_batch_prometheus_remote_write;
-
- instance->prepare_header = prometheus_remote_write_prepare_header;
- instance->check_response = process_prometheus_remote_write_response;
-
- instance->buffer = (void *)buffer_create(0, &netdata_buffers_statistics.buffers_exporters);
-
- if (uv_mutex_init(&instance->mutex))
- return 1;
- if (uv_cond_init(&instance->cond_var))
- return 1;
-
- struct simple_connector_data *simple_connector_data = callocz(1, sizeof(struct simple_connector_data));
- instance->connector_specific_data = simple_connector_data;
-
-#ifdef ENABLE_HTTPS
- simple_connector_data->ssl = NETDATA_SSL_UNSET_CONNECTION;
- if (instance->config.options & EXPORTING_OPTION_USE_TLS) {
- netdata_ssl_initialize_ctx(NETDATA_SSL_EXPORTING_CTX);
- }
-#endif
-
- struct prometheus_remote_write_specific_data *connector_specific_data =
- callocz(1, sizeof(struct prometheus_remote_write_specific_data));
- simple_connector_data->connector_specific_data = (void *)connector_specific_data;
-
- simple_connector_init(instance);
-
- connector_specific_data->write_request = init_write_request();
-
- instance->engine->protocol_buffers_initialized = 1;
-
- return 0;
-}
-
-struct format_remote_write_label_callback {
- struct instance *instance;
- void *write_request;
-};
-
-static int format_remote_write_label_callback(const char *name, const char *value, RRDLABEL_SRC ls __maybe_unused, void *data)
-{
- struct format_remote_write_label_callback *d = (struct format_remote_write_label_callback *)data;
-
- if (!should_send_label(d->instance, ls)) return 0;
- 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);
- add_label(d->write_request, k, v);
- return 1;
-}
-
-/**
- * Format host data for Prometheus Remote Write connector
- *
- * @param instance an instance data structure.
- * @param host a data collecting host.
- * @return Always returns 0.
- */
-int format_host_prometheus_remote_write(struct instance *instance, RRDHOST *host)
-{
- struct simple_connector_data *simple_connector_data =
- (struct simple_connector_data *)instance->connector_specific_data;
- struct prometheus_remote_write_specific_data *connector_specific_data =
- (struct prometheus_remote_write_specific_data *)simple_connector_data->connector_specific_data;
-
- char hostname[PROMETHEUS_ELEMENT_MAX + 1];
- prometheus_label_copy(
- hostname,
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host),
- PROMETHEUS_ELEMENT_MAX);
-
- add_host_info(
- connector_specific_data->write_request,
- "netdata_info", hostname, rrdhost_program_name(host), rrdhost_program_version(host), now_realtime_usec() / USEC_PER_MS);
-
- if (unlikely(sending_labels_configured(instance))) {
- struct format_remote_write_label_callback tmp = {
- .write_request = connector_specific_data->write_request,
- .instance = instance
- };
- rrdlabels_walkthrough_read(host->rrdlabels, format_remote_write_label_callback, &tmp);
- }
-
- return 0;
-}
-
-/**
- * Format chart data for Prometheus Remote Write connector
- *
- * @param instance an instance data structure.
- * @param st a chart.
- * @return Always returns 0.
- */
-int format_chart_prometheus_remote_write(struct instance *instance, RRDSET *st)
-{
- prometheus_label_copy(
- chart,
- (instance->config.options & EXPORTING_OPTION_SEND_NAMES && st->name) ? rrdset_name(st) : rrdset_id(st),
- PROMETHEUS_ELEMENT_MAX);
- prometheus_label_copy(family, rrdset_family(st), PROMETHEUS_ELEMENT_MAX);
- prometheus_name_copy(context, rrdset_context(st), PROMETHEUS_ELEMENT_MAX);
-
- as_collected = (EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AS_COLLECTED);
- homogeneous = 1;
- 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;
- } else {
- if (EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AVERAGE)
- prometheus_units_copy(units, rrdset_units(st), PROMETHEUS_ELEMENT_MAX, 0);
- }
-
- return 0;
-}
-
-/**
- * Format dimension data for Prometheus Remote Write connector
- *
- * @param instance an instance data structure.
- * @param rd a dimension.
- * @return Always returns 0.
- */
-int format_dimension_prometheus_remote_write(struct instance *instance, RRDDIM *rd)
-{
- struct simple_connector_data *simple_connector_data =
- (struct simple_connector_data *)instance->connector_specific_data;
- struct prometheus_remote_write_specific_data *connector_specific_data =
- (struct prometheus_remote_write_specific_data *)simple_connector_data->connector_specific_data;
-
- if (rd->collector.counter && !rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) {
- char name[PROMETHEUS_LABELS_MAX + 1];
- char dimension[PROMETHEUS_ELEMENT_MAX + 1];
- char *suffix = "";
- RRDHOST *host = rd->rrdset->rrdhost;
-
- if (as_collected) {
- // we need as-collected / raw data
-
- if (unlikely(rd->collector.last_collected_time.tv_sec < instance->after)) {
- netdata_log_debug(
- D_EXPORTING,
- "EXPORTING: not sending dimension '%s' of chart '%s' from host '%s', "
- "its last data collection (%lu) is not within our timeframe (%lu to %lu)",
- rrddim_id(rd), rrdset_id(rd->rrdset),
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host),
- (unsigned long)rd->collector.last_collected_time.tv_sec,
- (unsigned long)instance->after,
- (unsigned long)instance->before);
- return 0;
- }
-
- if (rd->algorithm == RRD_ALGORITHM_INCREMENTAL || rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
- if (strcmp(rrdset_module_name(rd->rrdset), "prometheus"))
- suffix = "_total";
- }
-
- if (homogeneous) {
- // all the dimensions of the chart, has the same algorithm, multiplier and divisor
- // we add all dimensions as labels
-
- prometheus_label_copy(
- dimension,
- (instance->config.options & EXPORTING_OPTION_SEND_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
- PROMETHEUS_ELEMENT_MAX);
- snprintf(name, PROMETHEUS_LABELS_MAX, "%s_%s%s", instance->config.prefix, context, suffix);
-
- add_metric(
- connector_specific_data->write_request,
- name, chart, family, dimension,
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host),
- rd->collector.last_collected_value, timeval_msec(&rd->collector.last_collected_time));
- } else {
- // the dimensions of the chart, do not have the same algorithm, multiplier or divisor
- // we create a metric per dimension
-
- prometheus_name_copy(
- dimension,
- (instance->config.options & EXPORTING_OPTION_SEND_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
- PROMETHEUS_ELEMENT_MAX);
- snprintf(
- name, PROMETHEUS_LABELS_MAX, "%s_%s_%s%s", instance->config.prefix, context, dimension,
- suffix);
-
- add_metric(
- connector_specific_data->write_request,
- name, chart, family, NULL,
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host),
- rd->collector.last_collected_value, timeval_msec(&rd->collector.last_collected_time));
- }
- } else {
- // we need average or sum of the data
-
- time_t last_t = instance->before;
- NETDATA_DOUBLE value = exporting_calculate_value_from_stored_data(instance, rd, &last_t);
-
- if (!isnan(value) && !isinf(value)) {
- if (EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_AVERAGE)
- suffix = "_average";
- else if (EXPORTING_OPTIONS_DATA_SOURCE(instance->config.options) == EXPORTING_SOURCE_DATA_SUM)
- suffix = "_sum";
-
- prometheus_label_copy(
- dimension,
- (instance->config.options & EXPORTING_OPTION_SEND_NAMES && rd->name) ? rrddim_name(rd) : rrddim_id(rd),
- PROMETHEUS_ELEMENT_MAX);
- snprintf(
- name, PROMETHEUS_LABELS_MAX, "%s_%s%s%s", instance->config.prefix, context, units, suffix);
-
- add_metric(
- connector_specific_data->write_request,
- name, chart, family, dimension,
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host),
- value, last_t * MSEC_PER_SEC);
- }
- }
- }
-
- return 0;
-}
-
-static int format_variable_prometheus_remote_write_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rv_ptr __maybe_unused, void *data) {
- const RRDVAR_ACQUIRED *rv = (const RRDVAR_ACQUIRED *)item;
-
- struct prometheus_remote_write_variables_callback_options *opts = data;
-
- if (rrdvar_flags(rv) & (RRDVAR_FLAG_CUSTOM_HOST_VAR | RRDVAR_FLAG_CUSTOM_CHART_VAR)) {
- RRDHOST *host = opts->host;
- struct instance *instance = opts->instance;
- struct simple_connector_data *simple_connector_data =
- (struct simple_connector_data *)instance->connector_specific_data;
- struct prometheus_remote_write_specific_data *connector_specific_data =
- (struct prometheus_remote_write_specific_data *)simple_connector_data->connector_specific_data;
-
- char name[PROMETHEUS_LABELS_MAX + 1];
- char *suffix = "";
-
- prometheus_name_copy(context, rrdvar_name(rv), PROMETHEUS_ELEMENT_MAX);
- snprintf(name, PROMETHEUS_LABELS_MAX, "%s_%s%s", instance->config.prefix, context, suffix);
-
- NETDATA_DOUBLE value = rrdvar2number(rv);
- add_variable(connector_specific_data->write_request, name,
- (host == localhost) ? instance->config.hostname : rrdhost_hostname(host), value, opts->now / USEC_PER_MS);
- }
-
- return 0;
-}
-
-/**
- * Format a variable for Prometheus Remote Write connector
- *
- * @param rv a variable.
- * @param instance an instance data structure.
- * @return Always returns 0.
- */
-int format_variables_prometheus_remote_write(struct instance *instance, RRDHOST *host)
-{
- struct prometheus_remote_write_variables_callback_options opt = {
- .host = host,
- .instance = instance,
- .now = now_realtime_usec(),
- };
-
- return rrdvar_walkthrough_read(host->rrdvars, format_variable_prometheus_remote_write_callback, &opt);
-}
-
-/**
- * Format a batch for Prometheus Remote Write connector
- *
- * @param instance an instance data structure.
- * @return Returns 0 on success, 1 on failure.
- */
-int format_batch_prometheus_remote_write(struct instance *instance)
-{
- struct simple_connector_data *simple_connector_data =
- (struct simple_connector_data *)instance->connector_specific_data;
- struct prometheus_remote_write_specific_data *connector_specific_data =
- (struct prometheus_remote_write_specific_data *)simple_connector_data->connector_specific_data;
-
- size_t data_size = get_write_request_size(connector_specific_data->write_request);
-
- if (unlikely(!data_size)) {
- netdata_log_error("EXPORTING: write request size is out of range");
- return 1;
- }
-
- BUFFER *buffer = instance->buffer;
-
- buffer_need_bytes(buffer, data_size);
- if (unlikely(pack_and_clear_write_request(connector_specific_data->write_request, buffer->buffer, &data_size))) {
- netdata_log_error("EXPORTING: cannot pack write request");
- return 1;
- }
- buffer->len = data_size;
-
- simple_connector_end_batch(instance);
-
- return 0;
-}