/* * ctrl_metrics.c — P3-7: Operational metrics for the XCE controller. * * Defines the 7 atomic counters/gauges and the descriptor table used * for metric discovery. All variables are initialised to 0 at program * start (C guarantees this for file-scope variables), and are zeroed * explicitly by ctrl_metrics_init() which is called from persist_start() * so that tests can call it repeatedly without interference. */ #include "ctrl_metrics.h" #include #include #include /* ── Counter/gauge definitions ──────────────────────────────────────── */ _Atomic uint64_t ctrl_repl_degraded_count = 0; _Atomic uint64_t ctrl_split_brain_detected = 0; _Atomic uint64_t ctrl_async_events_lost = 0; _Atomic uint64_t ctrl_transient_jobs_stuck = 0; _Atomic uint64_t ctrl_wal_bytes = 0; _Atomic uint64_t ctrl_checkpoint_duration_ms = 0; _Atomic uint64_t ctrl_repl_lag_lsn = 0; /* ── Descriptor table ───────────────────────────────────────────────── */ const ctrl_metric_desc_t ctrl_metric_descriptors[] = { { "ctrl_repl_degraded_count", &ctrl_repl_degraded_count, "Sync replication fallbacks to local-only durability", 1 }, { "ctrl_split_brain_detected", &ctrl_split_brain_detected, "Term conflicts indicating split-brain risk", 1 }, { "ctrl_async_events_lost", &ctrl_async_events_lost, "Async WAL entries lost during failover", 1 }, { "ctrl_transient_jobs_stuck", &ctrl_transient_jobs_stuck, "TRANSIENT jobs auto-terminated after timeout", 1 }, { "ctrl_wal_bytes", &ctrl_wal_bytes, "Current WAL size in bytes", 0 }, { "ctrl_checkpoint_duration_ms", &ctrl_checkpoint_duration_ms, "Duration of last checkpoint in milliseconds", 0 }, { "ctrl_repl_lag_lsn", &ctrl_repl_lag_lsn, "LSN gap between primary and slowest standby", 0 }, { NULL, NULL, NULL, 0 } /* sentinel */ }; /* ── ctrl_metrics_init ──────────────────────────────────────────────── */ void ctrl_metrics_init(void) { atomic_store_explicit(&ctrl_repl_degraded_count, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_split_brain_detected, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_async_events_lost, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_transient_jobs_stuck, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_wal_bytes, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_checkpoint_duration_ms, 0, memory_order_relaxed); atomic_store_explicit(&ctrl_repl_lag_lsn, 0, memory_order_relaxed); }