v0.24.0 — Pre-testing observability: debug logging, diagnostic dump, startup self-test

- Add [DEBUG] logging across all modules (backup, storage, sync, selfupdate,
  monitor, notify, report, assets, setup) gated behind logging.level: "debug"
- Add /api/debug/dump endpoint returning full controller state JSON (debug only)
- Add startup self-test validating 9 subsystems (Docker, dirs, storage, hub,
  restic repos, metrics DB) with pass/warn/fail summary
- New packages: internal/selftest, internal/util
- Constructor/signature changes: debug bool params, logger params on
  RunHealthCheck and BuildReport, smart watchdog probe logging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 18:32:26 +01:00
parent 6f02536243
commit be7803c0ac
30 changed files with 1281 additions and 67 deletions
+22 -1
View File
@@ -4,6 +4,7 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"log"
"os"
"strconv"
"strings"
@@ -29,7 +30,13 @@ func BuildReport(
metricsStore *metrics.MetricsStore,
version string,
storagePaths []settings.StoragePath,
logger *log.Logger,
) *Report {
debug := cfg.Logging.Level == "debug"
if debug && logger != nil {
logger.Printf("[DEBUG] BuildReport: starting — version=%s, storagePaths=%d", version, len(storagePaths))
}
r := &Report{
Version: 1,
CustomerID: cfg.Customer.ID,
@@ -48,6 +55,9 @@ func BuildReport(
if data, err := os.ReadFile(configPath); err == nil {
h := sha256.Sum256(data)
r.ConfigHash = hex.EncodeToString(h[:])
if debug && logger != nil {
logger.Printf("[DEBUG] BuildReport: configHash=%s (%d bytes)", r.ConfigHash[:12]+"...", len(data))
}
}
}
@@ -111,6 +121,12 @@ func BuildReport(
})
}
if debug && logger != nil {
logger.Printf("[DEBUG] BuildReport: system info collected — cpu=%.1f%%, mem=%d/%dMB, temp=%.1fC",
sysInfo.CPUPercent, sysInfo.UsedMemMB, sysInfo.TotalMemMB, sysInfo.TemperatureCelsius)
logger.Printf("[DEBUG] BuildReport: storage entries=%d", len(r.Storage))
}
// Containers
r.Containers = buildContainerReport(stackMgr, metricsStore)
@@ -118,7 +134,7 @@ func BuildReport(
r.Backup = buildBackupReport(cfg, backupMgr)
// Health
healthReport := monitor.RunHealthCheck(cfg, cpuCollector, storagePaths)
healthReport := monitor.RunHealthCheck(cfg, cpuCollector, storagePaths, logger)
r.Health = HealthReport{
Status: healthReport.Status,
Issues: healthReport.Issues,
@@ -134,6 +150,11 @@ func BuildReport(
// Stacks
r.Stacks = buildStacksReport(stackMgr)
if debug && logger != nil {
logger.Printf("[DEBUG] BuildReport: complete — containers=%d, health=%s, deployed=%d, available=%d",
r.Containers.Total, r.Health.Status, len(r.Stacks.Deployed), len(r.Stacks.Available))
}
return r
}