Persist dashboard backup metrics separately
This commit is contained in:
@@ -70,8 +70,32 @@ func (s *Store) SaveRuns(runs []model.Run) error {
|
||||
return writeJSONAtomic(s.runsPath(), runs, 0600)
|
||||
}
|
||||
|
||||
func (s *Store) LoadBackupMetrics() ([]model.BackupMetric, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
var metrics []model.BackupMetric
|
||||
if err := readJSON(s.backupMetricsPath(), &metrics); errors.Is(err, os.ErrNotExist) {
|
||||
return []model.BackupMetric{}, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
func (s *Store) SaveBackupMetrics(metrics []model.BackupMetric) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if len(metrics) > 5000 {
|
||||
metrics = metrics[len(metrics)-5000:]
|
||||
}
|
||||
return writeJSONAtomic(s.backupMetricsPath(), metrics, 0600)
|
||||
}
|
||||
|
||||
func (s *Store) configPath() string { return filepath.Join(s.dir, "config.json") }
|
||||
func (s *Store) runsPath() string { return filepath.Join(s.dir, "runs.json") }
|
||||
func (s *Store) backupMetricsPath() string {
|
||||
return filepath.Join(s.dir, "backup-metrics.json")
|
||||
}
|
||||
|
||||
func readJSON(path string, target any) error {
|
||||
b, err := os.ReadFile(path)
|
||||
|
||||
@@ -3,6 +3,7 @@ package store
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.casaderoll.de/michael/urbm/internal/model"
|
||||
)
|
||||
@@ -28,3 +29,32 @@ func TestStoreInitializesAndPersists(t *testing.T) {
|
||||
t.Fatalf("config mode = %o", info.Mode().Perm())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackupMetricsPersistSeparatelyFromRuns(t *testing.T) {
|
||||
s := New(t.TempDir())
|
||||
if err := s.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
finished := time.Date(2026, 7, 13, 1, 30, 0, 0, time.UTC)
|
||||
metrics := []model.BackupMetric{{SchemaVersion: model.SchemaVersion, RunID: "run-1", JobID: "job-1", FinishedAt: finished, Status: "success", BytesProcessed: 42, FilesProcessed: 7}}
|
||||
if err := s.SaveBackupMetrics(metrics); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := s.SaveRuns(nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
loaded, err := s.LoadBackupMetrics()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(loaded) != 1 || loaded[0].RunID != "run-1" || loaded[0].BytesProcessed != 42 {
|
||||
t.Fatalf("backup metrics = %#v", loaded)
|
||||
}
|
||||
info, err := os.Stat(s.backupMetricsPath())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if info.Mode().Perm() != 0600 {
|
||||
t.Fatalf("backup metrics mode = %o", info.Mode().Perm())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user