This commit is contained in:
Peter Li 2026-02-07 19:58:53 -08:00
parent 556935a59e
commit 765dd3229e
3 changed files with 15 additions and 0 deletions

View File

@ -84,13 +84,16 @@ func (a *app) executeJob(ctx context.Context, job store.Job) {
} }
func (a *app) runPreflightJob(ctx context.Context, job store.Job, site store.Site) (string, string) { func (a *app) runPreflightJob(ctx context.Context, job store.Job, site store.Site) (string, string) {
a.log.Debug("preflight begin", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID), zap.Int("targets", len(site.Targets)))
failures := 0 failures := 0
warnings := 0 warnings := 0
requiredLocal := []string{"ssh", "rsync", "restic", "gzip"} requiredLocal := []string{"ssh", "rsync", "restic", "gzip"}
for _, tool := range requiredLocal { for _, tool := range requiredLocal {
a.log.Debug("preflight local tool check", zap.Int64("job_id", job.ID), zap.String("tool", tool))
if _, err := exec.LookPath(tool); err != nil { if _, err := exec.LookPath(tool); err != nil {
failures++ failures++
a.log.Debug("preflight local tool missing", zap.Int64("job_id", job.ID), zap.String("tool", tool), zap.Error(err))
_ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "error", Message: fmt.Sprintf("local tool missing: %s", tool)}) _ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "error", Message: fmt.Sprintf("local tool missing: %s", tool)})
} }
} }
@ -98,13 +101,17 @@ func (a *app) runPreflightJob(ctx context.Context, job store.Job, site store.Sit
return "failed", fmt.Sprintf("preflight failed: %d local tool checks failed", failures) return "failed", fmt.Sprintf("preflight failed: %d local tool checks failed", failures)
} }
a.log.Debug("preflight ssh connectivity check", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID))
if err := sshCheck(ctx, site, "echo preflight-ok"); err != nil { if err := sshCheck(ctx, site, "echo preflight-ok"); err != nil {
_ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "error", Message: "ssh connectivity failed: " + err.Error()}) _ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "error", Message: "ssh connectivity failed: " + err.Error()})
a.log.Debug("preflight ssh connectivity failed", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID), zap.Error(err))
return "failed", "preflight failed: ssh connectivity" return "failed", "preflight failed: ssh connectivity"
} }
a.log.Debug("preflight ssh connectivity ok", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID))
_ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "info", Message: "ssh connectivity ok"}) _ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "info", Message: "ssh connectivity ok"})
for _, t := range site.Targets { for _, t := range site.Targets {
a.log.Debug("preflight target check begin", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID), zap.String("target_path", t.Path), zap.String("target_mode", t.Mode))
var err error var err error
switch t.Mode { switch t.Mode {
case "directory": case "directory":
@ -119,8 +126,10 @@ func (a *app) runPreflightJob(ctx context.Context, job store.Job, site store.Sit
warnings++ warnings++
msg := fmt.Sprintf("target %s (%s): %s", t.Path, t.Mode, err.Error()) msg := fmt.Sprintf("target %s (%s): %s", t.Path, t.Mode, err.Error())
_ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "warn", Message: msg}) _ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "warn", Message: msg})
a.log.Debug("preflight target check failed", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID), zap.String("target_path", t.Path), zap.String("target_mode", t.Mode), zap.Error(err))
} else { } else {
_ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "info", Message: fmt.Sprintf("target ok: %s (%s)", t.Path, t.Mode)}) _ = a.store.AddJobEvent(ctx, store.JobEvent{JobID: job.ID, Level: "info", Message: fmt.Sprintf("target ok: %s (%s)", t.Path, t.Mode)})
a.log.Debug("preflight target check ok", zap.Int64("job_id", job.ID), zap.Int64("site_id", site.ID), zap.String("target_path", t.Path), zap.String("target_mode", t.Mode))
} }
} }

View File

@ -48,6 +48,7 @@ func main() {
logger.Fatal("failed to open store", zap.Error(err), zap.String("db_path", dbPath)) logger.Fatal("failed to open store", zap.Error(err), zap.String("db_path", dbPath))
} }
defer st.Close() defer st.Close()
st.SetLogger(logger)
a := &app{store: st, log: logger} a := &app{store: st, log: logger}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())

View File

@ -95,22 +95,26 @@ func (a *app) scanSiteNow(ctx context.Context, siteID int64) {
a.log.Warn("scan site load failed", zap.Int64("site_id", siteID), zap.Error(err)) a.log.Warn("scan site load failed", zap.Int64("site_id", siteID), zap.Error(err))
return return
} }
a.log.Debug("scan site begin", zap.Int64("site_id", siteID), zap.Int("targets", len(site.Targets)))
scannedAt := time.Now() scannedAt := time.Now()
success := 0 success := 0
failures := 0 failures := 0
updated := make([]store.SiteTarget, 0, len(site.Targets)) updated := make([]store.SiteTarget, 0, len(site.Targets))
for _, target := range site.Targets { for _, target := range site.Targets {
a.log.Debug("scan target begin", zap.Int64("site_id", site.ID), zap.String("target_path", target.Path), zap.String("target_mode", target.Mode))
size, outErr := queryTargetSize(ctx, site, target) size, outErr := queryTargetSize(ctx, site, target)
target.LastScanAt = sql.NullTime{Time: scannedAt, Valid: true} target.LastScanAt = sql.NullTime{Time: scannedAt, Valid: true}
if outErr != nil { if outErr != nil {
failures++ failures++
target.LastSizeByte = sql.NullInt64{} target.LastSizeByte = sql.NullInt64{}
target.LastError = sql.NullString{String: outErr.Error(), Valid: true} target.LastError = sql.NullString{String: outErr.Error(), Valid: true}
a.log.Debug("scan target failed", zap.Int64("site_id", site.ID), zap.String("target_path", target.Path), zap.String("target_mode", target.Mode), zap.Error(outErr))
} else { } else {
success++ success++
target.LastSizeByte = sql.NullInt64{Int64: size, Valid: true} target.LastSizeByte = sql.NullInt64{Int64: size, Valid: true}
target.LastError = sql.NullString{} target.LastError = sql.NullString{}
a.log.Debug("scan target ok", zap.Int64("site_id", site.ID), zap.String("target_path", target.Path), zap.String("target_mode", target.Mode), zap.Int64("size_bytes", size))
} }
updated = append(updated, target) updated = append(updated, target)
} }
@ -125,6 +129,7 @@ func (a *app) scanSiteNow(ctx context.Context, siteID int64) {
state = "partial" state = "partial"
} }
notes := fmt.Sprintf("%d/%d targets scanned", success, len(site.Targets)) notes := fmt.Sprintf("%d/%d targets scanned", success, len(site.Targets))
a.log.Debug("scan site complete", zap.Int64("site_id", site.ID), zap.String("state", state), zap.String("notes", notes))
if err := a.store.UpdateSiteScanResult(ctx, site.ID, state, notes, scannedAt, updated); err != nil { if err := a.store.UpdateSiteScanResult(ctx, site.ID, state, notes, scannedAt, updated); err != nil {
a.log.Warn("scan site update failed", zap.Int64("site_id", siteID), zap.Error(err)) a.log.Warn("scan site update failed", zap.Int64("site_id", siteID), zap.Error(err))
} }