v0.83.0: observability pass — always-DEBUG capture ring + GET /debug/logs + heartbeat log-pull + gap-fill sweep
Capture layer: applog.New returns (logger, Ring) — slog fan-out, stderr at the configured level, ~1000-entry ring fixed at LevelDebug (remote diagnostics without a config flip). GET /debug/logs (token-authed, ?raw=1) + request-level DEBUG middleware. Heartbeat log-pull mirrors the report logtail pattern: envelope log_tail_requested -> next heartbeat carries log_tail (128KB cap, consume-once, failed-push retry proven). Gap-fill sweep over netverify/ netstorage/netmount/signedjobs/selfupdate/disks/controller-swap/desired/loop. Red-proofs: ring-at-emit-level FAILs capture test; drain removed FAILs consume-once; dropped phase line FAILs the S7 log-sequence smoke. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -241,6 +241,7 @@ func (c *ControllerSwapper) Swap(ctx context.Context, vmid int, target string) *
|
||||
c.saveState(st) // crash-safety: previous recorded BEFORE any mutation
|
||||
|
||||
// The controller pre-pulled the image; refuse to swap to an absent image (would brick the guest).
|
||||
c.logger.Debug("controller-swap: pre-pull verify", "vmid", vmid, "target", target, "previous", prev)
|
||||
if !c.imagePresent(ctx, vmid, target) {
|
||||
st.State = "failed"
|
||||
st.Error = "target image not present in guest (controller did not pre-pull it)"
|
||||
@@ -270,6 +271,7 @@ func (c *ControllerSwapper) Swap(ctx context.Context, vmid int, target string) *
|
||||
c.logger.Info("controller-swap: new controller healthy", "vmid", vmid, "target", target)
|
||||
return st
|
||||
}
|
||||
c.logger.Warn("controller-swap: health verdict negative — rolling back", "vmid", vmid, "target", target)
|
||||
return c.rollback(ctx, st, "new controller did not become healthy within timeout")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user