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:
@@ -47,12 +47,13 @@ type Syncer struct {
|
||||
fallbackDir string // /usr/share/felhom/assets — baked-in fallback
|
||||
httpClient *http.Client
|
||||
logger *log.Logger
|
||||
debug bool
|
||||
mu sync.Mutex
|
||||
status SyncStatus
|
||||
}
|
||||
|
||||
// New creates a Syncer that downloads assets from the Hub.
|
||||
func New(hubURL, apiKey, assetsDir, fallbackDir string, logger *log.Logger) *Syncer {
|
||||
func New(hubURL, apiKey, assetsDir, fallbackDir string, logger *log.Logger, debug bool) *Syncer {
|
||||
return &Syncer{
|
||||
hubURL: strings.TrimSuffix(hubURL, "/"),
|
||||
apiKey: apiKey,
|
||||
@@ -60,6 +61,7 @@ func New(hubURL, apiKey, assetsDir, fallbackDir string, logger *log.Logger) *Syn
|
||||
fallbackDir: fallbackDir,
|
||||
httpClient: &http.Client{Timeout: 60 * time.Second},
|
||||
logger: logger,
|
||||
debug: debug,
|
||||
status: SyncStatus{LastStatus: "never"},
|
||||
}
|
||||
}
|
||||
@@ -78,11 +80,17 @@ func (s *Syncer) Sync(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// 1. Fetch Hub manifest
|
||||
if s.debug {
|
||||
s.logger.Printf("[DEBUG] Asset sync: fetching manifest from %s/api/v1/assets/manifest", s.hubURL)
|
||||
}
|
||||
manifest, err := s.fetchManifest(ctx)
|
||||
if err != nil {
|
||||
s.setError(fmt.Errorf("fetch manifest: %w", err))
|
||||
return err
|
||||
}
|
||||
if s.debug {
|
||||
s.logger.Printf("[DEBUG] Asset sync: manifest has %d files", len(manifest.Files))
|
||||
}
|
||||
|
||||
// 2. Build local hash map
|
||||
localHashes, err := s.buildLocalHashes()
|
||||
@@ -90,6 +98,9 @@ func (s *Syncer) Sync(ctx context.Context) error {
|
||||
s.setError(fmt.Errorf("scan local assets: %w", err))
|
||||
return err
|
||||
}
|
||||
if s.debug {
|
||||
s.logger.Printf("[DEBUG] Asset sync: %d local files found", len(localHashes))
|
||||
}
|
||||
|
||||
// 3. Download changed/new files
|
||||
hubFiles := make(map[string]bool, len(manifest.Files))
|
||||
@@ -105,6 +116,9 @@ func (s *Syncer) Sync(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if s.debug {
|
||||
s.logger.Printf("[DEBUG] Asset sync: downloading %s (remote sha256=%s)", entry.Filename, entry.SHA256[:12]+"...")
|
||||
}
|
||||
if err := s.downloadFile(ctx, entry.Filename); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to download asset %s: %v", entry.Filename, err)
|
||||
continue
|
||||
@@ -117,6 +131,9 @@ func (s *Syncer) Sync(ctx context.Context) error {
|
||||
for name := range localHashes {
|
||||
if !hubFiles[name] {
|
||||
path := filepath.Join(s.assetsDir, name)
|
||||
if s.debug {
|
||||
s.logger.Printf("[DEBUG] Asset sync: removing stale file %s", name)
|
||||
}
|
||||
if err := os.Remove(path); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to remove stale asset %s: %v", name, err)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user