feat(health): SiteAuditBacklog metric (count + age + bytes) (#23 M6)

This commit is contained in:
Joseph Doherty
2026-05-20 19:02:01 -04:00
parent 75b060e0a8
commit e93f655ce4
11 changed files with 511 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
using ScadaLink.Commons.Messages.Health;
using ScadaLink.Commons.Types;
using ScadaLink.Commons.Types.Enums;
namespace ScadaLink.HealthMonitoring;
@@ -28,6 +29,15 @@ public interface ISiteHealthCollector
/// <c>AddAuditLogHealthMetricsBridge()</c>.
/// </summary>
void IncrementAuditRedactionFailure();
/// <summary>
/// Audit Log (#23) M6 Bundle E (T6) — replace the latest site-local
/// audit-queue backlog snapshot (pending count, oldest pending row,
/// on-disk file bytes) used by the next <see cref="CollectReport"/> call.
/// Refreshed periodically by the <c>SiteAuditBacklogReporter</c> hosted
/// service so each report carries a recent point-in-time view of the
/// site→central drain health.
/// </summary>
void UpdateSiteAuditBacklog(SiteAuditBacklogSnapshot snapshot);
void UpdateConnectionHealth(string connectionName, ConnectionHealth health);
void RemoveConnection(string connectionName);
void UpdateTagResolution(string connectionName, int totalSubscribed, int successfullyResolved);

View File

@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using ScadaLink.Commons.Messages.Health;
using ScadaLink.Commons.Types;
using ScadaLink.Commons.Types.Enums;
namespace ScadaLink.HealthMonitoring;
@@ -15,6 +16,7 @@ public class SiteHealthCollector : ISiteHealthCollector
private int _deadLetterCount;
private int _siteAuditWriteFailures;
private int _auditRedactionFailures;
private volatile SiteAuditBacklogSnapshot? _siteAuditBacklog;
private readonly ConcurrentDictionary<string, ConnectionHealth> _connectionStatuses = new();
private readonly ConcurrentDictionary<string, TagResolutionStatus> _tagResolutionCounts = new();
private readonly ConcurrentDictionary<string, string> _connectionEndpoints = new();
@@ -89,6 +91,18 @@ public class SiteHealthCollector : ISiteHealthCollector
Interlocked.Increment(ref _auditRedactionFailures);
}
/// <summary>
/// Audit Log (#23) M6 Bundle E (T6) — replace the latest backlog snapshot
/// from the site SQLite writer. The field is a single reference write
/// (volatile) so the next <see cref="CollectReport"/> sees the most recent
/// snapshot — there is no count to reset, the report just carries forward
/// whatever was last refreshed.
/// </summary>
public void UpdateSiteAuditBacklog(SiteAuditBacklogSnapshot snapshot)
{
_siteAuditBacklog = snapshot ?? throw new ArgumentNullException(nameof(snapshot));
}
/// <summary>
/// Update the health status for a named data connection.
/// Called by DCL when connection state changes.
@@ -207,6 +221,7 @@ public class SiteHealthCollector : ISiteHealthCollector
ParkedMessageCount: Interlocked.CompareExchange(ref _parkedMessageCount, 0, 0),
ClusterNodes: _clusterNodes?.ToList(),
SiteAuditWriteFailures: siteAuditWriteFailures,
AuditRedactionFailure: auditRedactionFailures);
AuditRedactionFailure: auditRedactionFailures,
SiteAuditBacklog: _siteAuditBacklog);
}
}