feat(health): wire ISiteEventLogger.FailedWriteCount into SiteHealthReport (#30, M2.16)

Add SiteHealthReport.SiteEventLogWriteFailures (trailing optional long = 0,
additive-only), ISiteHealthCollector.SetSiteEventLogWriteFailures (default
no-op so existing fakes compile), and SiteEventLogFailureCountReporter
(hosted service in HealthMonitoring, Func<long> delegate to avoid the
HealthMonitoring → StoreAndForward → SiteEventLogging cycle).

Registration helper AddSiteEventLogHealthMetricsBridge added to
HealthMonitoring.ServiceCollectionExtensions; wired in
SiteServiceRegistration after AddSiteEventLogging.

Tests: SiteEventLogWriteFailuresMetricTests (4 collector tests) +
SiteEventLogFailureCountReporterTests (2 poller tests) in
HealthMonitoring.Tests. 79/79 HealthMonitoring.Tests green,
59/59 SiteEventLogging.Tests green, 0 warnings.
This commit is contained in:
Joseph Doherty
2026-06-16 07:14:54 -04:00
parent e1ee37e508
commit d81f747434
9 changed files with 394 additions and 6 deletions
@@ -40,7 +40,14 @@ public record SiteHealthReport(
// hosted service every 30 s. Defaults to null so existing producers /
// tests that don't refresh the snapshot stay valid; the central health
// surface treats null as "no data yet" rather than a zeroed queue.
SiteAuditBacklogSnapshot? SiteAuditBacklog = null);
SiteAuditBacklogSnapshot? SiteAuditBacklog = null,
// Site Event Logging (#12) M2.16 (#30): cumulative count of event-log write
// failures (SQLite error, disk full, bounded-queue overflow drop) since the
// logger was created. Populated by the site-side SiteEventLogFailureCountReporter
// hosted service. Point-in-time (not reset on collect) — mirrors the
// SiteAuditBacklog pattern. Defaults to 0 so existing producers / tests that
// don't wire the poller stay valid.
long SiteEventLogWriteFailures = 0);
/// <summary>
/// Broadcast wrapper used between central nodes to keep per-node