From b3a4449856f555e31d9d5bb05e2c889ba5601d48 Mon Sep 17 00:00:00 2001 From: zydo Date: Thu, 18 Jun 2026 19:55:14 +0000 Subject: [PATCH] Surface engine cooldown and classify network-level blocks on /monitor The /monitor page showed Yahoo as "healthy" while it was being blocked, and gave no indication of which engines the scraper had benched. Two gaps, both fixed here. Recognize network-level blocks: classify_engine and the scraper's cooldown tracker only treated HTTP 429/403/503 as a block, but Yahoo blocks at the TCP layer (net::ERR_CONNECTION_CLOSED) with no HTTP status, so it slipped through as healthy/degraded and was never benched. A new common/block_signals.is_network_block recognizes connection-level teardowns (not plain timeouts); it feeds both the cooldown tracker (Yahoo now gets benched instead of eating a nav timeout every cycle) and classify_engine (labelled "blocked" despite a NULL status). The metrics aggregate now carries last_error_message so the API can see it. Surface cooldown state: the EngineCooldownTracker lives in the scraper process and the API couldn't see it, so there was no "cooling down" concept at all. The scraper now snapshots tracker state to a new engine_cooldowns table each cycle (next_probe_at as absolute UTC, since the monotonic clock can't cross processes); /metrics overlays a "cooldown" health label with a probe countdown and synthesizes rows for benched engines that produced no logs, so they stay visible instead of vanishing. A stale snapshot (scraper down) is ignored. Docs (README, OBSERVABILITY, API_REFERENCE, BLOCK_SIGNAL_*) updated. --- README.md | 4 +- api/static/monitor.html | 2 +- api/static/monitor.js | 19 ++++ api/static/styles.css | 7 ++ api/v1/metrics.py | 105 ++++++++++++++++++++-- common/block_signals.py | 42 +++++++++ common/database.py | 69 +++++++++++++- docs/API_REFERENCE.md | 6 +- docs/BLOCK_SIGNAL_CHARACTERIZATION.md | 7 +- docs/BLOCK_SIGNAL_FINDINGS.md | 17 ++-- docs/OBSERVABILITY.md | 15 +++- postgres/init.sql | 14 +++ scraper/cooldown.py | 34 ++++++- scraper/main.py | 14 +++ tests/integration/conftest.py | 4 +- tests/integration/test_api_integration.py | 35 ++++++++ tests/test_engine_cooldown.py | 37 ++++++++ tests/test_metrics.py | 79 +++++++++++++++- 18 files changed, 480 insertions(+), 30 deletions(-) create mode 100644 common/block_signals.py diff --git a/README.md b/README.md index 9e1a224..388c761 100644 --- a/README.md +++ b/README.md @@ -183,10 +183,10 @@ http://localhost:5000 A built-in observability console at **`/monitor`** (linked from the wire masthead) gives a per-engine, per-cycle view of scraper health — no Prometheus/Grafana stack required, since the data already lives in Postgres. It polls [`GET /api/v1/metrics`](docs/API_REFERENCE.md#metrics) over a selectable window (1h / 6h / 24h) and shows: - **Overall strip** - active topics, total filed, scrape success rate, feed freshness, last-cycle duration, and scrapes-in-window (blocked / failed). -- **Engines table** - one row per engine with a health label (`healthy` / `degraded` / `blocked` / `parsing` / `idle`), success %, fetch latency (avg / p95), items parsed, 0-parse count (selector-rot signal), blocks (429/403/503), and last HTTP status. +- **Engines table** - one row per engine with a health label (`healthy` / `degraded` / `blocked` / `parsing` / `cooldown` / `idle`), success %, fetch latency (avg / p95), items parsed, 0-parse count (selector-rot signal), blocks (429/403/503), and last HTTP status. `blocked` now also covers connection-level teardowns with no HTTP status (e.g. Yahoo's `ERR_CONNECTION_CLOSED`). - **Recent cycles** - a sparkline of per-cycle durations plus a list (duration, topics, parsed, new events). -A throttled engine shows up here rather than silently vanishing from the feed — below, Brave reads `degraded` with its block count while Google/Bing/Yahoo stay `healthy`. See [Observability](docs/OBSERVABILITY.md) for details. +A throttled engine shows up here rather than silently vanishing from the feed. When the scraper benches an engine, the table shows `cooldown` with a countdown to the next probe — so an engine that produces no scrapes while cooling stays visible instead of disappearing. See [Observability](docs/OBSERVABILITY.md) for details.

TopicStreams /monitor ops page - per-engine health table and recent-cycle timeline diff --git a/api/static/monitor.html b/api/static/monitor.html index 9866cb8..492c9e8 100644 --- a/api/static/monitor.html +++ b/api/static/monitor.html @@ -103,7 +103,7 @@

Recent failures