From 11b71d54e95143e136bc399b4fedb9af769c6bfb Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 9 May 2022 14:15:06 +0200 Subject: [PATCH] Add namespace and labels to go internal metrics --- metrics/metrics_runtime.go | 68 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/metrics/metrics_runtime.go b/metrics/metrics_runtime.go index bce7e25..2218bdd 100644 --- a/metrics/metrics_runtime.go +++ b/metrics/metrics_runtime.go @@ -1,12 +1,17 @@ package metrics import ( + "bufio" + "bytes" + "fmt" "io" + "strings" vm "github.com/VictoriaMetrics/metrics" "github.com/safing/portbase/api" "github.com/safing/portbase/config" + "github.com/safing/portbase/log" ) func registerRuntimeMetric() error { @@ -29,6 +34,65 @@ type runtimeMetrics struct { } func (r *runtimeMetrics) WritePrometheus(w io.Writer) { - // TODO: Add global labels. - vm.WriteProcessMetrics(w) + // If there nothing to change, just write directly to w. + if metricNamespace == "" && len(globalLabels) == 0 { + vm.WriteProcessMetrics(w) + return + } + + // Write metrics to buffer. + buf := new(bytes.Buffer) + vm.WriteProcessMetrics(buf) + + // Add namespace and label per line. + scanner := bufio.NewScanner(buf) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + line := scanner.Text() + + // Add namespace, if set. + if metricNamespace != "" { + line = metricNamespace + "_" + line + } + + // Add global labels, if set. + if len(globalLabels) > 0 { + // Find where to insert. + mergeWithExisting := true + insertAt := strings.Index(line, "{") + 1 + if insertAt <= 0 { + mergeWithExisting = false + insertAt = strings.Index(line, " ") + if insertAt < 0 { + continue + } + } + + // Write new line directly to w. + fmt.Fprint(w, line[:insertAt]) + if !mergeWithExisting { + fmt.Fprint(w, "{") + } + labelsAdded := 0 + for labelKey, labelValue := range globalLabels { + fmt.Fprintf(w, "%s=%q", labelKey, labelValue) + // Add separator if not last label. + labelsAdded++ + if labelsAdded < len(globalLabels) { + fmt.Fprint(w, ", ") + } + } + if mergeWithExisting { + fmt.Fprint(w, ", ") + } else { + fmt.Fprint(w, "}") + } + fmt.Fprintln(w, line[insertAt:]) + } + } + + // Check if there was an error in the scanner. + if scanner.Err() != nil { + log.Warningf("metrics: failed to scan go process metrics: %s", scanner.Err()) + } }