Files
jarl/internal/server/h_storage.go
T
adamandClaude Opus 5.5 250e734046 Query log wording: N answers so far, each kept for 7 days
"The query log holds 7 answers (stats.retention.queries)" read like 7 days' worth. The dashboard and the Statistics page now say how many answers it holds and how long each is kept; the dashboard's storage info has query_log_retention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:27:56 +01:00

80 lines
2.2 KiB
Go

package server
import (
"context"
"os"
"path/filepath"
"slices"
"jarl/internal/api"
"jarl/internal/stats"
)
// storage reports the size of Jarl's databases and how full the disks
// Jarl uses are (the dashboard's Storage card).
func (s *Server) storage(ctx context.Context) *api.Storage {
out := &api.Storage{Databases: []api.Database{}, Disks: []api.Disk{}}
dbFile := func(label, path string) *api.Database {
if path == "" || path == ":memory:" {
return nil
}
d := api.Database{Label: label, Path: path, Bytes: dbBytes(path)}
out.Databases = append(out.Databases, d)
out.Total += d.Bytes
return &out.Databases[len(out.Databases)-1]
}
labels := []string{}
dirs := map[string]string{}
add := func(label, dir string) {
if dir != "" {
labels = append(labels, label)
dirs[label] = dir
}
}
const jarlDB, statsDB = "Jarl's database", "statistics database"
if p := s.store.Path(); p != "" {
dbFile(jarlDB, p)
add(jarlDB, filepath.Dir(p))
}
if s.cfg.Stats != nil {
if p := s.cfg.Stats.Store().Path(); p != "" && p != ":memory:" {
if d := dbFile(statsDB, p); d != nil && s.cfg.Stats.Options().RetainQueries > 0 {
if n, err := s.cfg.Stats.Store().QueryLogSize(ctx); err == nil {
d.QueryLogRows = &n
d.QueryLogRetention = s.cfg.Stats.Status().Retention.Queries
}
}
add(statsDB, filepath.Dir(p))
}
if lf := s.cfg.Stats.Options().LogFile; lf != "" {
add("named's logs", filepath.Dir(lf))
}
}
paths := s.eng.Config().Paths
add("zone files", paths.ZoneDir)
add("named.conf", paths.ConfigDir)
add("Jarl's cache and blocklists", paths.CacheDir)
add("backups", s.cfg.BackupDir)
for _, d := range stats.DiskUsage(labels, dirs) {
disk := api.Disk{Path: d.Path, Holds: d.Holds, Total: d.Total, Free: d.Free}
for _, db := range out.Databases {
if slices.Contains(d.Holds, db.Label) {
disk.Databases += db.Bytes
}
}
out.Disks = append(out.Disks, disk)
}
return out
}
// dbBytes is the size of a SQLite database: its file, -wal and -shm.
func dbBytes(path string) int64 {
var n int64
for _, suffix := range []string{"", "-wal", "-shm"} {
if fi, err := os.Stat(path + suffix); err == nil {
n += fi.Size()
}
}
return n
}