The tab collected over SSH on every 30s poll — 8.3s a load with HOST2 down. vv_parse_conf_scalar() captured to end of line, so a commented toggle parsed as "true # HOST2 back online": every threshold read right because (int) stops at the first non-digit, and 38 booleans read wrong. The Fallback tab has been showing failover disabled while it was on.
74 lines
4.1 KiB
PHP
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 HOST2 down —
|
|
// 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);
|