feat(audit-log): surface partition-purge failure as health event + counter

This commit is contained in:
Joseph Doherty
2026-07-09 06:49:28 -04:00
parent b59aa2d717
commit 14c4df54f9
9 changed files with 202 additions and 5 deletions
+17 -1
View File
@@ -390,9 +390,25 @@ MS SQL for direct-write events). Unredacted secrets never persist.
- **Purge actor:** `AuditLogPurgeActor` singleton on the active central node
runs daily, switches out any partition whose latest `OccurredAtUtc` is older
than the retention window, then applies any per-channel overrides (see below),
and emits an `AuditLog:Purged` event (partition range, rowcount, duration) per
and emits an `AuditLogPurgedEvent` (partition range, rowcount, duration) per
switched partition. A partition-maintenance step rolls forward each month,
creating the next month's partition ahead of time.
- **Purge failure is a health metric, not just a log line:** every purge step that
throws — a partition switch-out, a per-channel override DELETE, or the pre-purge
boundary enumeration — publishes an `AuditLogPurgeFailedEvent` (month boundary,
error message, elapsed ms; `DateTime.MinValue` boundary for the enumeration/channel
phases that have no single month in hand) and increments the `PurgeFailures` central
health counter on `AuditCentralHealthSnapshot` (alongside `CentralAuditWriteFailures`).
This is the symmetric failure twin of the success-path `AuditLogPurgedEvent`: a
silently failing retention job would otherwise be invisible until the table grew
unbounded. Per-boundary/per-channel error isolation is unchanged — a single failure
still never abandons the rest of the tick.
- **Maintenance command timeout:** the switch-out drop-and-rebuild dance and each
per-channel `DELETE TOP` batch run with an explicit command timeout
(`AuditLog:Purge:MaintenanceCommandTimeoutMinutes`, default 30, floor 1 min) rather
than the ~30 s ADO.NET default, which could abort the metadata-only SWITCH mid-dance
on a large or contended partition and leave the live table without
`UX_AuditLog_EventId` until a later tick's CATCH branch rebuilt it.
- **Per-channel retention overrides (M5.5 T3):** `AuditLog:PerChannelRetentionDays`
is a dictionary keyed by canonical channel name (`ApiOutbound`, `DbOutbound`,
`Notification`, `ApiInbound`) whose value is a retention window in days that