From 675cbbf24a098dd77481f320bb7073320a446946 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 22 Jan 2024 13:56:59 +0100 Subject: [PATCH] Add netdata_os_info metric (#16756) --- exporting/prometheus/prometheus.c | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/exporting/prometheus/prometheus.c b/exporting/prometheus/prometheus.c index d6a896f4eba888..4563fbf2dbb8f3 100644 --- a/exporting/prometheus/prometheus.c +++ b/exporting/prometheus/prometheus.c @@ -526,6 +526,88 @@ static void generate_as_collected_prom_metric(BUFFER *wb, buffer_sprintf(wb, "\n"); } +static void prometheus_print_os_info( + BUFFER *wb, + RRDHOST *host, + PROMETHEUS_OUTPUT_OPTIONS output_options) +{ + FILE *fp; + char filename[FILENAME_MAX + 1]; + char buf[BUFSIZ + 1]; + int first_line = 1; + + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/etc/os-release"); + fp = fopen(filename, "r"); + if (!fp) { + /* Fallback to lsb-release */ + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/etc/lsb-release"); + fp = fopen(filename, "r"); + } + if (!fp) { + return; + } + + buffer_sprintf(wb, "netdata_os_info{instance=\"%s\"", rrdhost_hostname(host)); + + while (fgets(buf, BUFSIZ, fp)) { + char *in, *sanitized; + char *key, *val; + int in_val_part = 0; + + /* sanitize the line */ + sanitized = in = buf; + in_val_part = 0; + while (*in && *in != '\n') { + if (!in_val_part) { + /* Only accepts alphabetic characters and '_' + * in key part */ + if (isalpha(*in) || *in == '_') { + *(sanitized++) = tolower(*in); + } else if (*in == '=') { + in_val_part = 1; + *(sanitized++) = '='; + } + } else { + /* Don't accept special characters in + * value part */ + switch (*in) { + case '"': + case '\'': + case '\r': + case '\t': + break; + default: + if (isprint(*in)) { + *(sanitized++) = *in; + } + } + } + in++; + } + /* Terminate the string */ + *(sanitized++) = '\0'; + + /* Split key/val */ + key = buf; + val = strchr(buf, '='); + + /* If we have a key/value pair, add it as a label */ + if (val) { + *val = '\0'; + val++; + buffer_sprintf(wb, ",%s=\"%s\"", key, val); + first_line = 0; + } + } + + /* Finish the line */ + if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS) + buffer_sprintf(wb, "} 1 %llu\n", now_realtime_usec() / USEC_PER_MS); + else + buffer_sprintf(wb, "} 1\n"); + + fclose(fp); +} /** * Write metrics in Prometheus format to a buffer. * @@ -579,6 +661,9 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus( if (instance->labels_buffer) buffer_flush(instance->labels_buffer); + if (instance->config.options & EXPORTING_OPTION_SEND_AUTOMATIC_LABELS) + prometheus_print_os_info(wb, host, output_options); + // send custom variables set for the host if (output_options & PROMETHEUS_OUTPUT_VARIABLES) {