Skip to content

feat(collector): add durable collector-host health monitoring - #735

Merged
proerror77 merged 6 commits into
mainfrom
codex/collector-monitoring
Aug 7, 2026
Merged

proerror77 merged 6 commits into
mainfrom
codex/collector-monitoring

Conversation

@proerror77

@proerror77 proerror77 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Change contract

Add durable on-host monitoring so a silent disk-full (all governed collectors
down, uploads failing, delay-gate trips accumulating) can never go unnoticed
again. New monday-collector-health.sh (POSIX, read-only) emits one JSON
snapshot and exits nonzero on breach: /data mount, disk warn<25%/crit<10%,
governed units active+enabled+Result=success+restart-rate delta, incident fill
sources (bybit-options-archiver, polymarket-raw-ops-gate@) must stay
disabled, health.json freshness/sequence_gaps, upload-status last_error /
failure_count delta, and journald delay-gate trips. Runs from a hardened
oneshot service + 5-min timer (no ConditionPathIsMountPoint, so a missing /data
is detected). Primary alert channel is a Cloud Monitor disk alarm (JSON in
README); fallback is a GitHub Actions 15-min workflow invoking the script via
Cloud Assistant and opening a deduped needs-triage issue.

Issue relationship

None

Out of scope

  • Live host install of the service/timer and the Cloud Monitor alarm (separate
    named-controller runtime cutover with host readback).
  • The governed-restore, polymarket raw-ops, and bybit contracts (separate
    branches).

Dependencies and merge order

None. Based on a74ee6f4; no file overlap with the other remediation branches.

Focused validation

  • bash -n monday-collector-health.sh test-monday-collector-health.sh — PASS
  • ./test-monday-collector-health.sh — PASS (47 assertions: healthy baseline,
    disk crit/warn, inactive unit, timer not enabled, Result failure, restart
    delta, health stale/gap/missing, upload error/delta, delay-gate trips, mount
    unmounted, bybit enabled, poly gate indirect, missing upload-status not a
    breach, JSON shape healthy/breaching, dry-run writes no state)
  • git diff --check — clean; workflow YAML parses.

Rollout and rollback

Production impact is None until an operator installs the service/timer and
alarm on the host. Rollback of the script: revert the commit. The README
documents the governed install/rollback template (named controller, source
identity, stop rules).

Scope exception

6 files / 1296 non-generated lines exceeds the 750-line default. This is one
inseparable monitoring contract (script + unit + timer + test + alarm + fallback
workflow). Named reviewer (repository owner) approved the full diff in
docs/reviews/2026-08-07-incident-remediation-diff-review.md.

Summary by CodeRabbit

  • New Features

    • Added automated collector-host health monitoring on a five-minute schedule, with optional manual checks.
    • Monitors storage, service availability, upload health, watchdog status, delay conditions, and required filesystem mounts.
    • Reports results in readable or JSON formats and records health-check failures.
    • Automatically creates or updates deduplicated triage issues when health breaches or monitoring failures occur.
  • Documentation

    • Added deployment guidance for installing the health monitor, systemd scheduling, disk alarms, and fallback monitoring.

Add a read-only on-host health monitor (monday-collector-health.sh + systemd
service/timer) that guards against a silent recurrence of the 2026-08-05/06
disk-full incident, plus two alert channels: an Aliyun Cloud Monitor disk
alarm (primary) and a scheduled GitHub Actions workflow (fallback) that opens
a needs-triage issue on breach.

Checks: /data mount and disk free (<25% warn, <10% crit), governed service
active+enabled+Result==success with restart-rate delta, upload timer/lane
status, watchdog timer/service, incident fill source stays disabled, health.json
freshness/gaps, upload last_error/failure_count delta, and delay-gate trips.
The monitor is read-only toward units and never modifies tape or status files.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@proerror77, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 33 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dec73a8d-72ee-4449-aef4-d2f1c9f9b02a

📥 Commits

Reviewing files that changed from the base of the PR and between e5477b4 and 0fa7943.

📒 Files selected for processing (3)
  • .github/workflows/monitor-collector-host.yml
  • deployment/aliyun/monday-collector-health.sh
  • deployment/aliyun/test-monday-collector-health.sh
📝 Walkthrough

Walkthrough

Adds a read-only collector host health monitor with systemd scheduling, fixture-based contract tests, Aliyun Cloud Assistant execution, and deduplicated GitHub issue reporting for health breaches and invocation failures.

Changes

Collector Health Monitoring

Layer / File(s) Summary
Health monitor implementation
deployment/aliyun/monday-collector-health.sh
Adds mount, disk, systemd, health-file, upload, watchdog, disabled-unit, and delay-gate checks. The script emits JSON or text, persists comparison state, supports dry runs, and returns failure status for breaches.
Systemd scheduling and deployment
deployment/aliyun/monday-collector-health.service, deployment/aliyun/monday-collector-health.timer, deployment/aliyun/README.md
Adds a hardened oneshot service and five-minute persistent timer. Documents installation, rollback, verification, and mount handling.
Health monitor contract tests
deployment/aliyun/test-monday-collector-health.sh
Adds isolated fixtures and 20 scenarios for thresholds, service state, persisted deltas, health files, upload status, delay gates, JSON output, and dry-run behavior.
Aliyun invocation and issue triage
.github/workflows/monitor-collector-host.yml, deployment/aliyun/README.md
Adds scheduled and manual Cloud Assistant checks, result polling, JSON parsing, scoped credentials, disk alarms, and deduplicated issue creation or updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant AliyunCloudAssistant
  participant CollectorHost
  participant GitHubIssues
  GitHubActions->>AliyunCloudAssistant: Invoke collector health script
  AliyunCloudAssistant->>CollectorHost: Run monday-collector-health.sh
  CollectorHost-->>AliyunCloudAssistant: Return health JSON and exit code
  AliyunCloudAssistant-->>GitHubActions: Return invocation result
  GitHubActions->>GitHubIssues: Create or update deduplicated triage issue
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: durable collector-host health monitoring.
Description check ✅ Passed The description completes all template sections and provides the behavior, rationale, scope, validation, rollout, rollback, and scope-exception details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/collector-monitoring

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread .github/workflows/monitor-collector-host.yml Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/monitor-collector-host.yml:
- Around line 164-174: Add a workflow or job-level concurrency group with
cancel-in-progress set to false so issue handling runs are serialized; retain
the existing lookup in .github/workflows/monitor-collector-host.yml lines
164-174 and apply the same serialized issue path at lines 190-199.
- Around line 111-144: Update the terminal-state handling loop to process Cloud
Assistant Output for Failed, Stopped, PartialFailed, and Timeout states using
the same decoding and `.ok` JSON validation as successful states. Treat a
nonzero exit code as a valid command result, and set invocation_failed=1 only
when no valid health snapshot exists and no useful exit/result was produced;
preserve diagnostic logging for terminal failures.
- Around line 45-48: Update the Aliyun CLI installation steps before aliyun
version to use an exact, pinned release archive instead of the latest URL,
download the matching official SHA-256 checksum, verify the archive against it,
and only then extract and install it.

In `@deployment/aliyun/monday-collector-health.sh`:
- Around line 334-342: Update write_state to record a breach whenever state
persistence fails: state-directory creation, temporary-file creation, or the
final mv/rename must trigger the existing breach mechanism before returning or
cleaning up. Preserve the current dry-run behavior and successful atomic write
flow.
- Around line 323-325: Update the trip-counting logic near the journalctl
pipeline to capture journalctl’s exit status separately instead of masking
failures with || true. Preserve a successful no-match query as trips=0, but
treat a failed journalctl query as a breach so the monitor cannot report ok:true
without inspectable evidence.
- Around line 252-253: Update the health-file validation around health_file to
reject symbolic links by requiring the path to be a regular file and not a
symlink before accepting it; preserve record_breach for missing or invalid
files. Add a symbolic-link fixture covering this validation, following the
regular non-symbolic health-file contract used by host-rust-lob-cutover.sh.

In `@deployment/aliyun/test-monday-collector-health.sh`:
- Around line 280-281: Remove the BSD/GNU dual-command fallback and use one
supported sed scenario-rewrite implementation at
deployment/aliyun/test-monday-collector-health.sh lines 280-281, 293-294,
306-307, 321-322, 421-422, and 434-435. Apply the same direct replacement
consistently at every site without suppressing errors or silently retrying with
another sed variant.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 447b8b86-0e90-4694-aeaa-90a6b6399210

📥 Commits

Reviewing files that changed from the base of the PR and between 728e983 and e5477b4.

📒 Files selected for processing (6)
  • .github/workflows/monitor-collector-host.yml
  • deployment/aliyun/README.md
  • deployment/aliyun/monday-collector-health.service
  • deployment/aliyun/monday-collector-health.sh
  • deployment/aliyun/monday-collector-health.timer
  • deployment/aliyun/test-monday-collector-health.sh

Comment thread .github/workflows/monitor-collector-host.yml Outdated
Comment thread .github/workflows/monitor-collector-host.yml
Comment thread .github/workflows/monitor-collector-host.yml
Comment thread deployment/aliyun/monday-collector-health.sh Outdated
Comment thread deployment/aliyun/monday-collector-health.sh Outdated
Comment thread deployment/aliyun/monday-collector-health.sh Outdated
Comment thread deployment/aliyun/test-monday-collector-health.sh Outdated
Sonic Shih added 2 commits August 7, 2026 18:52
Addresses CodeRabbit review threads blocking PR #735:

- write_state: record a breach when the state directory, temp file, or
  rename fails, so a monitor that cannot persist restart/upload deltas
  cannot report healthy.
- check_delay_gate: capture journalctl's own exit status; a failed query
  means delay-gate evidence was uninspectable and is itself a breach.
- check_binance_health: reject health.json when it is a symbolic link.
- Test harness: replace the BSD/GNU dual sed -i fallback with one
  portable temp-file rewrite helper; add fixtures for symlink health.json,
  journald query failure, and state-persistence failure (53 pass).
…ize runs

Addresses CodeRabbit review threads blocking PR #735:

- Install the Aliyun CLI from a pinned, SHA-verified v3.4.11 release
  instead of the mutable latest URL.
- Decode the command Output in every terminal invocation state. The
  health script exits nonzero on a breach, so a Failed/Stopped/PartialFailed/
  Timeout invocation still carries a valid ok:false snapshot that must be
  surfaced rather than treated as a monitor failure.
- Serialize runs via a concurrency group so overlapping ticks cannot both
  open a duplicate needs-triage issue.
@proerror77
proerror77 merged commit d280d31 into main Aug 7, 2026
45 checks passed
@proerror77
proerror77 deleted the codex/collector-monitoring branch August 7, 2026 11:01
proerror77 pushed a commit that referenced this pull request Aug 7, 2026
DELAY_GATE_WINDOW=15min is not a valid journalctl timestamp; the host
rejects it with 'Failed to parse timestamp: 15min', so both LOB units
reported a permanent 'journald query failed' breach after the #735
install. Use '15 min ago', verified against journalctl on the target
host. The mock-journalctl harness never exercised timestamp parsing.
proerror77 added a commit that referenced this pull request Aug 7, 2026
…739)

DELAY_GATE_WINDOW=15min is not a valid journalctl timestamp; the host
rejects it with 'Failed to parse timestamp: 15min', so both LOB units
reported a permanent 'journald query failed' breach after the #735
install. Use '15 min ago', verified against journalctl on the target
host. The mock-journalctl harness never exercised timestamp parsing.

Co-authored-by: Sonic Shih <sonic.shih@mandonothing.com>
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