From f0f68e485f5f2f4f28ca1fbc40fa14b6dce9f8ff Mon Sep 17 00:00:00 2001 From: Valentin Doreau Date: Sun, 21 Apr 2024 15:22:29 +0200 Subject: [PATCH] fix: store new metrics in buffer before resetting Borg repo information can take a long time to gather. Before resetting the old metrics we store the new ones in a buffer and update everything at the end. --- buffer.go | 14 ++++++++++++++ main.go | 25 ++++++++++++++----------- metrics.go | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 buffer.go diff --git a/buffer.go b/buffer.go new file mode 100644 index 0000000..9c6d007 --- /dev/null +++ b/buffer.go @@ -0,0 +1,14 @@ +package main + +type MetricsBuffer struct { + RepoName string + ArchiveCount float64 + LastArchiveTime float64 + LastModified float64 + TotalChunks float64 + TotalCsize float64 + TotalSize float64 + TotalUniqueChunks float64 + UniqueCsize float64 + UniqueSize float64 +} diff --git a/main.go b/main.go index 7059fcf..8bac142 100644 --- a/main.go +++ b/main.go @@ -57,13 +57,12 @@ func main() { func RecordMetrics(m Metrics) { for { - m.Reset() - entries, err := os.ReadDir(*backupDir) if err != nil { log.Fatalln(err) } + buffer := []MetricsBuffer{} for _, entry := range entries { if !entry.IsDir() || strings.HasPrefix(entry.Name(), ".") { log.Printf(">> Ignoring %v\n", entry.Name()) @@ -86,17 +85,21 @@ func RecordMetrics(m Metrics) { stats := info.Cache.Stats log.Printf("> Got info for: %v\n", path) - m.ArchiveCount.With(prometheus.Labels{"repo_name": entry.Name()}).Set(float64(len(list.Archives))) - m.LastArchiveTime.With(prometheus.Labels{"repo_name": entry.Name()}).Set(list.LastArchiveUnix()) - m.LastModified.With(prometheus.Labels{"repo_name": entry.Name()}).Set(info.LastmodUnix()) - m.TotalChunks.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Total_chunks) - m.TotalCsize.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Total_csize) - m.TotalSize.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Total_size) - m.TotalUniqueChunks.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Total_unique_chunks) - m.UniqueCsize.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Unique_csize) - m.UniqueSize.With(prometheus.Labels{"repo_name": entry.Name()}).Set(stats.Unique_size) + buffer = append(buffer, MetricsBuffer{ + RepoName: entry.Name(), + ArchiveCount: float64(len(list.Archives)), + LastArchiveTime: list.LastArchiveUnix(), + LastModified: info.LastmodUnix(), + TotalChunks: stats.Total_chunks, + TotalCsize: stats.Total_csize, + TotalSize: stats.Total_size, + TotalUniqueChunks: stats.Total_unique_chunks, + UniqueCsize: stats.Unique_csize, + UniqueSize: stats.Unique_size, + }) } + m.Update(buffer) log.Printf("> Waiting %v\n", INTERVAL) time.Sleep(INTERVAL) } diff --git a/metrics.go b/metrics.go index 2bd005c..f755e52 100644 --- a/metrics.go +++ b/metrics.go @@ -56,3 +56,21 @@ func (m *Metrics) Reset() { m.UniqueCsize.Reset() m.UniqueSize.Reset() } + +// Update these metrics with the given buffer. +// +// Resets the metrics beforehand. Expected to be called on every loop iteration. +func (m *Metrics) Update(buffer []MetricsBuffer) { + m.Reset() + for _, buf := range buffer { + m.ArchiveCount.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.ArchiveCount) + m.LastArchiveTime.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.LastArchiveTime) + m.LastModified.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.LastModified) + m.TotalChunks.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.TotalChunks) + m.TotalCsize.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.TotalCsize) + m.TotalSize.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.TotalSize) + m.TotalUniqueChunks.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.TotalUniqueChunks) + m.UniqueCsize.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.UniqueCsize) + m.UniqueSize.With(prometheus.Labels{"repo_name": buf.RepoName}).Set(buf.UniqueSize) + } +}