Skip to content

feat: detect and report container OOM kills - #10

Merged
kfeofantov merged 1 commit into
mainfrom
feat/oom-detection
Jul 29, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
feat/oom-detection

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

First real finding signal: an OOM kill paired with the container's declared memory limit — the two facts that make the "limit too low" story.

What

  • internal/collector/oom.go: OOMKill event (namespace, pod, container, resolved workload, finishedAt, exit code, restart count, memory_limit_bytes) reported via a new PodWatcher.OnOOMKill callback
  • Detection covers both places a kill can sit: lastState.terminated (container restarted) and state.terminated (restartPolicy: Never), for init and regular containers
  • New UpdateFunc handler — OOM kills happen after the pod appears and arrive as status updates; the pod itself is not re-reported
  • Exactly-once reporting: dedup map keyed by container + finishedAt (the same kill moving from state to lastState keeps its key), purged on pod deletion. Losing the map on agent restart re-reports the same kill — harmless, per the loss-harmless state invariant
  • cmd/agent: logs oom kill observed at WARN

Scope

Uses only the pods read access already promised in docs/security.md §4, which names this exact detection (lastState.terminated.reason == "OOMKilled") — no doc change needed.

Verified

  • Unit: kill via status update reported once across further updates; kill already present at watcher start (cache replay); plain Error crash not reported
  • e2e on kind: a real 32Mi-limited busybox pod OOM-killed in ~13s, event asserted: exit 137, memory_limit_bytes: 33554432, bare-pod workload none
  • go test -race ./..., golangci-lint clean

🤖 Generated with Claude Code

The pod watcher now scans container statuses (init and regular) for
terminations with reason OOMKilled — both lastState (restarted
containers) and current state (restartPolicy Never) — and reports each
kill exactly once via a new OnOOMKill callback. The event pairs the
kill with the container's declared memory limit, plus finishedAt, exit
code, restart count, and the resolved workload.

OOM kills arrive as pod status updates, so the watcher gains an
UpdateFunc handler; deduplication is an in-memory map keyed by
container and finishedAt, purged on pod deletion. Losing it on agent
restart is harmless: the same kill is re-reported, never missed.

Uses only the pods/status access already promised in docs/security.md
§4, which names this exact detection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kfeofantov
kfeofantov merged commit e49a6a7 into main Jul 29, 2026
3 checks passed
@kfeofantov
kfeofantov deleted the feat/oom-detection branch August 9, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant