feat(health): metrics-stale signal + status-transition timestamps; spec now matches heartbeat-liveness code

This commit is contained in:
Joseph Doherty
2026-07-08 16:21:30 -04:00
parent 15d91d760f
commit c73b7faa11
7 changed files with 199 additions and 16 deletions
@@ -45,5 +45,24 @@ public sealed class HealthMonitoringOptionsValidator : OptionsValidatorBase<Heal
$"must be >= OfflineTimeout ({options.OfflineTimeout}): the synthetic 'central' site has " +
"no heartbeat source and is fed only by the slower self-report loop, so it needs at " +
"least as much offline grace as a real site.");
builder.RequireThat(options.MetricsStaleTimeout > TimeSpan.Zero,
$"ScadaBridge:HealthMonitoring:MetricsStaleTimeout must be a positive duration " +
$"(was {options.MetricsStaleTimeout}); it is the window an online site may go without " +
"a full report before being flagged metrics-stale.");
// A stale window shorter than one report interval flags every healthy
// site (reports simply can't arrive faster than they are emitted). Same
// De Morgan guard shape as the Central/Offline pair above: stay silent
// when either field is non-positive so the dedicated positive-duration
// checks own that failure rather than double-firing here.
builder.RequireThat(
!(options.ReportInterval > TimeSpan.Zero
&& options.MetricsStaleTimeout > TimeSpan.Zero
&& options.MetricsStaleTimeout < options.ReportInterval),
$"ScadaBridge:HealthMonitoring:MetricsStaleTimeout ({options.MetricsStaleTimeout}) " +
$"must be >= ReportInterval ({options.ReportInterval}): a stale window shorter than one " +
"report interval would flag every healthy site, since reports cannot arrive faster than " +
"they are emitted.");
}
}