From 18305caadb11ee7edefadc2437c26da1c7c72f98 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 16 Feb 2021 14:54:34 +0200 Subject: [PATCH] lib/httpserver: cache `/metrics` output for a second This should reduce CPU load when `/metrics` output is scraped with a frequency exceeding a request per second --- lib/httpserver/metrics.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/httpserver/metrics.go b/lib/httpserver/metrics.go index e577f5ce3a..a6a2a7bf03 100644 --- a/lib/httpserver/metrics.go +++ b/lib/httpserver/metrics.go @@ -6,9 +6,12 @@ import ( "io" "regexp" "strings" + "sync" + "sync/atomic" "time" "github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo" + "github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/memory" "github.com/VictoriaMetrics/metrics" @@ -18,6 +21,27 @@ var versionRe = regexp.MustCompile(`v\d+\.\d+\.\d+`) // WritePrometheusMetrics writes all the registered metrics to w in Prometheus exposition format. func WritePrometheusMetrics(w io.Writer) { + currentTime := time.Now() + metricsCacheLock.Lock() + if currentTime.Sub(metricsCacheLastUpdateTime) > time.Second { + var bb bytesutil.ByteBuffer + writePrometheusMetrics(&bb) + metricsCache.Store(&bb) + metricsCacheLastUpdateTime = currentTime + } + metricsCacheLock.Unlock() + + bb := metricsCache.Load().(*bytesutil.ByteBuffer) + w.Write(bb.B) +} + +var ( + metricsCacheLock sync.Mutex + metricsCacheLastUpdateTime time.Time + metricsCache atomic.Value +) + +func writePrometheusMetrics(w io.Writer) { metrics.WritePrometheus(w, true) metrics.WriteFDMetrics(w)