Skip to content

Claude/worker logs memory redis a7vsv8#131

Merged
maximusunc merged 5 commits into
mainfrom
claude/worker-logs-memory-redis-a7vsv8
Jul 17, 2026
Merged

Claude/worker logs memory redis a7vsv8#131
maximusunc merged 5 commits into
mainfrom
claude/worker-logs-memory-redis-a7vsv8

Conversation

@maximusunc

Copy link
Copy Markdown
Collaborator

No description provided.

claude and others added 5 commits July 15, 2026 18:57
Three fixes reported together:

- merge_message worker logs were missing from the terminal. b508bd7 demoted
  the worker's operational lines (obtained lock / drained N / finished task) from
  INFO to DEBUG to stop them flooding the query response log list; that also
  silenced them on the console (which runs at INFO). Route these plumbing lines
  through a dedicated `shepherd.merge_message` console logger that propagates to
  the console handler but carries no query_log_handler, restoring terminal
  visibility without re-polluting the stored query logs. Also fix the module-level
  pool-sizing / poll-loop lines that were logging to the unconfigured root logger.

- Monitor memory percentage. The per-replica worker table now shows RSS as a
  percentage of the container's memory cap (a new cgroup memory-limit read in the
  heartbeat, mirroring cpu_count; None when uncapped), and the Redis memory row
  inlines the % of maxmemory alongside used/cap.

- Redis eviction no longer spams inaccurate worker-down alerts. Key eviction does
  not disconnect workers, but under volatile-ttl it can evict their short-TTL
  heartbeat keys, so a live worker momentarily reads as zero-alive and the monitor
  fires bogus worker-down/crash alerts. Add a Redis-eviction grace window
  (mirroring the broker-recovery grace) that suppresses worker-down alerts while
  eviction is active and briefly after, so genuine losses still fire once it clears.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3Nn3SxzDnNwh2djT3orGs
Root-cause follow-up to the eviction-grace alert suppression: exempt the
heartbeat keys from eviction entirely instead of only papering over the false
alerts they cause.

The broker runs a volatile-ttl maxmemory policy, which evicts the keys nearest
to expiry first. Worker heartbeat keys carried a 15s TTL, making them the very
first thing shed under memory pressure -- so a live worker would vanish from the
keyspace and read as crashed, even though key eviction never actually
disconnects a worker. This mirrors the redis.conf design already in place for
the task streams, which are exempt precisely because they carry no TTL.

Write heartbeats as persistent keys (no TTL) and judge liveness from the
payload's last_seen timestamp instead of key existence. A shared
is_heartbeat_fresh() is now the single definition every "is this worker alive?"
reader uses -- the monitor poller (already last_seen-based), the task reclaimer,
and the janitor -- so they can't drift. Because a persistent key can't expire
itself when a worker crashes, the poller reaps heartbeats left unrefreshed past
HEARTBEAT_REAP_SEC (2 min) so dead consumers don't pile up or linger as phantom
stale rows; clean shutdown still deletes the key immediately.

Reclaim keeps its ~15s freshness cutoff (not the 2 min reap) and reads last_seen
directly, so crash-recovery latency is unchanged and never depends on the
monitor being up to reap.

Tests: persistent key has no TTL; is_heartbeat_fresh by last_seen; reclaim skips
a fresh owner but claims from a stale-but-present one; poller reaps dead keys.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3Nn3SxzDnNwh2djT3orGs
Back out the dedicated console_logger sidecar added for the merge_message
worker's operational lines. The plumbing lines return to their prior state
(logger.debug on the per-task query logger; module-level logging.info/error),
leaving the log-level decisions to be made directly per line instead.

The memory-percentage and Redis-eviction changes from the same original commit
are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3Nn3SxzDnNwh2djT3orGs
…recovery)

Replace the two independent redis_memory YAML threshold rules with an automatic
engine state machine, mirroring the broker/postgres health alerts. This fixes
three things about the old behavior:

- Tiering without duplicates: usage is classified into one level (ok / warning
  >=85% / critical >=95%), and only the current level alerts. Crossing the
  critical line no longer also sends the redundant warning alert.
- Backoff: while usage stays elevated it re-notifies at most once per
  monitor_redis_memory_cooldown_sec (a full day by default) instead of every
  10 minutes.
- Recovery: when usage falls back below the warning threshold it emits a
  redis_memory_recovered ("it's better") alert, like broker/postgres recovery.

A grace window debounces level changes so a single-tick spike or dip doesn't
alert or clear. Thresholds, grace, and cooldown are tunable via the new
monitor_redis_memory_* settings. Drops the now-unused redis_memory Rule type /
YAML rules; redis_eviction is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3Nn3SxzDnNwh2djT3orGs
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 74.82014% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.98%. Comparing base (f86de24) to head (e39a05f).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
shepherd_utils/heartbeat.py 45.71% 18 Missing and 1 partial ⚠️
workers/monitor/janitor.py 11.11% 8 Missing ⚠️
workers/monitor/alerts.py 95.58% 2 Missing and 1 partial ⚠️
workers/monitor/poller.py 76.92% 2 Missing and 1 partial ⚠️
workers/merge_message/worker.py 0.00% 1 Missing ⚠️
workers/monitor/worker.py 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
shepherd_utils/config.py 94.79% <100.00%> (+0.40%) ⬆️
shepherd_utils/reclaim.py 77.41% <100.00%> (+4.20%) ⬆️
workers/merge_message/worker.py 66.73% <0.00%> (ø)
workers/monitor/worker.py 0.00% <0.00%> (ø)
workers/monitor/alerts.py 65.92% <95.58%> (+3.96%) ⬆️
workers/monitor/poller.py 21.79% <76.92%> (+6.09%) ⬆️
workers/monitor/janitor.py 17.36% <11.11%> (-0.37%) ⬇️
shepherd_utils/heartbeat.py 54.36% <45.71%> (-1.78%) ⬇️

... and 3 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9df6b13...e39a05f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maximusunc
maximusunc merged commit acacfe0 into main Jul 17, 2026
2 checks passed
@maximusunc
maximusunc deleted the claude/worker-logs-memory-redis-a7vsv8 branch July 17, 2026 16:46
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.

2 participants