feat(observability): agent-health heartbeat emitting OTLP to SigNoz #389
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/infrastructure#389
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
There is no o11y on the agent serving layer. The local-model harnesses (goose, opencode, qwen) bind to Ollama on the tower over tailnet, and "why are the agents down/slow?" currently requires hand-curling the tower. Nothing feeds that signal into the o11y stack.
Build an always-on heartbeat as a third sibling to
scripts/process-memory-heartbeat.pyandthermal-heartbeat-install.sh:/api/version(up + round-trip latency),/api/ps(which model is resident,size_vram,expires_at), and GPU/VRAM via nvidia.4317/4318), not VictoriaMetrics/Grafana, so this survives the Grafana teardown (#388).Reuse existing probe logic: the reachability + residency probe is already prototyped in
agentic-osscripts/goose-health.sh(see coilyco-flight-deck/agentic-os#268 for that script's disposition). Lift the/api/version+/api/psparsing from there.Why it matters: the incident that surfaced this was VRAM contention -
qwen3-coder:30bevicted bydeepseek-v2:16bon the tower, so every goose call cold-loads. A residency + latency metric would have answered it instantly instead of four hops of manual investigation.Triage:
P2/headless- Agent-health heartbeat to SigNoz; well-specified, lifts existing goose-health probe logic.(goose-style pass; claude as the judgment engine, applied 2026-06-23)
🔒 Reserved by
ward agent --driver claude— containerengineer-claude-infrastructure-389on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-01T08:08:29Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - agent-health heartbeat landed on main (Ollama + GPU probe, OTLP to SigNoz, ansible user-timer, NodePort, glance dashboard), CI green.
Felt clean once the topology clicked. The two named siblings are root system-timers installed by shell scripts, but "fleet rollout via ansible" really pointed at the git-state-watch pattern, so I went with a no-sudo user systemd timer on kai-server. The one thing that actually fought back was pylint's duplicate-code check. My minimal OTLP encoder was a near-verbatim copy of process-memory-heartbeat's, so I pulled it into
scripts/_otlp.pyand moved both scripts onto it, addingas_doublefor the latency and utilization gauges. One encoder now instead of two.Confidence is high on the script itself. I decoded its payload against the real opentelemetry-proto library and round-tripped both the spilled-model detection and the RFC3339 keep-alive math. Lower on two deploy-time unknowns I could not exercise from inside the container: whether the NodePort selector matches the live SigNoz chart's otel-collector labels (I left the one-liner to confirm in the README), and whether kai-server resolves the tower's Ollama at
kai-tower-3026:11434. Both are label or env knobs, not code.Follow-ups worth filing: GPU rows only appear when the probe host has a card, so on kai-server they stay empty and the tower GPU keeps living on the Windows gpu-heartbeat path. If we want GPU-in-SigNoz we install the same role on a GPU Linux host. And the dashboard JSON is best-effort against the SigNoz v4 builder schema, so it may want a nudge on import.