From 046a7753e6196c4c3ef9280f96a483bfb9388153 Mon Sep 17 00:00:00 2001 From: hzhang Date: Wed, 3 Jun 2026 13:13:33 +0100 Subject: [PATCH] log monitor push start + slow heartbeat First successful push emits an info-level "monitor push started" so operators can confirm the loop wired up correctly. Subsequent successes log every 60 cycles ("monitor push heartbeat") so the journal stays quiet but still proves the loop isn't dead. Errors already log at warn; this fills the success-side gap so a silent journal can't hide a "no successes, no errors" pathology. --- internal/monitor/pusher.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/monitor/pusher.go b/internal/monitor/pusher.go index f0103ee..ff59427 100644 --- a/internal/monitor/pusher.go +++ b/internal/monitor/pusher.go @@ -166,11 +166,26 @@ func (p *Pusher) Stats() PushStats { func (p *Pusher) recordOK(status int) { p.mu.Lock() - defer p.mu.Unlock() + wasFirst := p.successHits == 0 p.lastSentAt = time.Now().UTC() p.lastStatus = status p.lastErr = "" p.successHits++ + count := p.successHits + p.mu.Unlock() + + // First success is an operator signal that the push loop is live; + // log it loud so the journal carries proof. Subsequent successes + // log on a slow heartbeat (every 60 cycles) so the journal stays + // quiet but still proves the loop hasn't drifted into "0 successes + // but no errors either" territory. + if wasFirst { + p.log("info", "monitor push started", map[string]any{"status": status}) + } else if count%60 == 0 { + p.log("info", "monitor push heartbeat", map[string]any{ + "successes": count, "status": status, + }) + } } func (p *Pusher) recordErr(msg string) {