Files
Varaverk/Plugin/unraid/api/watchdog.php
T
Gmer4Lfe 0447fa6f86 Remove point-in-time HOST2 status from the codebase
Comments asserting a partner is down, being rebuilt or not yet installed are true on the day they are written and wrong afterwards, and nothing prompts anyone to revisit them. Behaviour is described generically; current state belongs in operator memory, not in tracked files.
2026-08-17 15:20:25 -04:00

74 lines
4.1 KiB
PHP

<?php
// ═══════════════════════════════════════════════════════════════════════════════════════════════
// PURPOSE
// Watchdog data endpoint. Every watchdog's current state for every node in one document —
// resource, docker, system, storage, network and stability — together with the thresholds
// each one is judging against, for the watchdog tab's poll.
//
// DESIGN PRINCIPLES
// Thin transport. State-file parsing and threshold resolution live in
// include/watchdog.php; this file only sets the content type and encodes.
//
// Thresholds ship with the state, not separately.
// vv_wd_all() resolves every threshold from master.conf into the same payload as the
// counters they apply to. A strike count means nothing without the limit it is counted
// against, so the page never has to fetch the two independently and risk mismatching
// them across a conf edit.
//
// No parameters. Which watchdogs exist is fixed by the codebase, not by the request.
//
// OPERATIONAL SAFEGUARDS
// Read-only. Nothing here clears a strike, lifts a skip-list entry, restarts a container,
// or cancels a pending reboot. The watchdogs own their own state; this endpoint reports it.
//
// Absent counters are reported quiet, not alarming.
// A watchdog that has not yet written state reads as zero rather than unknown, so a
// fresh boot does not light the page up with false strikes.
//
// Thresholds fall back to the shipped defaults.
// Every vv_wd_scalar() lookup has a ?: default, so a master.conf that is mid-edit or
// missing a key still yields a coherent payload instead of comparing counters against
// zero and declaring everything critical.
//
// Remote collection degrades per node — one unreachable partner drops that node's card and
// leaves the local host and every other partner intact.
//
// Served from cache, collected only on a miss.
// vv_wd_all() SSHes to every configured partner, so its cost is set by the slowest node
// rather than by how much data there is. Measured at 8.3s on this host with the partner unreachable —
// paid by every visitor, every 30 seconds, because the tab polls. The cache check happens
// before the heavy include, so a hit costs one file read and no SSH at all.
//
// The window is deliberately wider than the poll. Watchdog state only changes when the
// orchestrator runs, which is every 15 minutes; polling it every 30 seconds was never
// reading anything new, it was just re-paying for the same answer.
//
// REQUEST
// GET served from the 300s cache when one is present
// GET ?live bypass the cache and collect everything fresh
//
// RESPONSE
// vv_wd_all() verbatim — per-node watchdog state plus the resolved threshold set
//
// DEPENDS ON
// include/config.php vv_cache_read()
// include/watchdog.php vv_wd_all() — required only on a miss
// Tools/api_cache_writer.php writes the cache this endpoint normally serves
// ═══════════════════════════════════════════════════════════════════════════════════════════════
header('Content-Type: application/json');
require_once dirname(__DIR__) . '/include/config.php';
if (!isset($_GET['live'])) {
$_vv_cached = vv_cache_read('watchdog', 300);
if ($_vv_cached !== null) { echo json_encode($_vv_cached); exit; }
unset($_vv_cached);
}
require_once dirname(__DIR__) . '/include/watchdog.php';
$_vv_wd = vv_wd_all();
// Written on the miss as well as by the background writer. Without this the first visitor after
// a restart pays the full collection and so does the next one, until the writer's next minute
// happens to land.
vv_cache_write('watchdog', $_vv_wd);
echo json_encode($_vv_wd);