Add netdata_os_info metric (#16756)
Colin Leroy-Mira committed
Jan 22, 2024 at 13:56 UTC
675cbbf24a098dd77481f320bb7073320a446946
1 file changed
+85
exporting/prometheus/prometheus.c
+85
@@ -526,6 +526,88 @@ static void generate_as_collected_prom_metric(BUFFER *wb,
526
buffer_sprintf(wb, "\n");
527
}
528
529
+static void prometheus_print_os_info(
530
+ BUFFER *wb,
531
+ RRDHOST *host,
532
+ PROMETHEUS_OUTPUT_OPTIONS output_options)
533
+{
534
+ FILE *fp;
535
+ char filename[FILENAME_MAX + 1];
536
+ char buf[BUFSIZ + 1];
537
+ int first_line = 1;
538
+
539
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/etc/os-release");
540
+ fp = fopen(filename, "r");
541
+ if (!fp) {
542
+ /* Fallback to lsb-release */
543
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/etc/lsb-release");
544
+ fp = fopen(filename, "r");
545
+ }
546
+ if (!fp) {
547
+ return;
548
+ }
549
+
550
+ buffer_sprintf(wb, "netdata_os_info{instance=\"%s\"", rrdhost_hostname(host));
551
+
552
+ while (fgets(buf, BUFSIZ, fp)) {
553
+ char *in, *sanitized;
554
+ char *key, *val;
555
+ int in_val_part = 0;
556
+
557
+ /* sanitize the line */
558
+ sanitized = in = buf;
559
+ in_val_part = 0;
560
+ while (*in && *in != '\n') {
561
+ if (!in_val_part) {
562
+ /* Only accepts alphabetic characters and '_'
563
+ * in key part */
564
+ if (isalpha(*in) || *in == '_') {
565
+ *(sanitized++) = tolower(*in);
566
+ } else if (*in == '=') {
567
+ in_val_part = 1;
568
+ *(sanitized++) = '=';
569
+ }
570
+ } else {
571
+ /* Don't accept special characters in
572
+ * value part */
573
+ switch (*in) {
574
+ case '"':
575
+ case '\'':
576
+ case '\r':
577
+ case '\t':
578
+ break;
579
+ default:
580
+ if (isprint(*in)) {
581
+ *(sanitized++) = *in;
582
+ }
583
+ }
584
+ }
585
+ in++;
586
+ }
587
+ /* Terminate the string */
588
+ *(sanitized++) = '\0';
589
+
590
+ /* Split key/val */
591
+ key = buf;
592
+ val = strchr(buf, '=');
593
+
594
+ /* If we have a key/value pair, add it as a label */
595
+ if (val) {
596
+ *val = '\0';
597
+ val++;
598
+ buffer_sprintf(wb, ",%s=\"%s\"", key, val);
599
+ first_line = 0;
600
+ }
601
+ }
602
+
603
+ /* Finish the line */
604
+ if (output_options & PROMETHEUS_OUTPUT_TIMESTAMPS)
605
+ buffer_sprintf(wb, "} 1 %llu\n", now_realtime_usec() / USEC_PER_MS);
606
+ else
607
+ buffer_sprintf(wb, "} 1\n");
608
+
609
+ fclose(fp);
610
+}
611
/**
612
* Write metrics in Prometheus format to a buffer.
613
*
@@ -579,6 +661,9 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(
661
if (instance->labels_buffer)
662
buffer_flush(instance->labels_buffer);
663
664
+ if (instance->config.options & EXPORTING_OPTION_SEND_AUTOMATIC_LABELS)
665
+ prometheus_print_os_info(wb, host, output_options);
666
+
667
// send custom variables set for the host
668
if (output_options & PROMETHEUS_OUTPUT_VARIABLES) {
669