Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.HealthMonitoring/ISiteHealthCollector.cs
T

221 lines
9.7 KiB
C#

using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring;
/// <summary>
/// Interface for site-side health metric collection.
/// Consumed by Site Runtime actors to report errors, and by DCL to report connection health.
/// </summary>
public interface ISiteHealthCollector
{
/// <summary>
/// Increments the script error count.
/// </summary>
void IncrementScriptError();
/// <summary>
/// Increments the alarm error count.
/// </summary>
void IncrementAlarmError();
/// <summary>
/// Increments the dead letter count.
/// </summary>
void IncrementDeadLetter();
/// <summary>
/// Increment the per-interval count of
/// <c>FallbackAuditWriter</c> primary failures. Bridged from the
/// <c>IAuditWriteFailureCounter</c> binding registered via
/// <c>AddAuditLogHealthMetricsBridge()</c>.
/// </summary>
void IncrementSiteAuditWriteFailures();
/// <summary>
/// Increment the per-interval count of
/// payload-filter redactor over-redactions (header / body / SQL
/// parameter stage throws routed to the
/// <c>&lt;redacted: redactor error&gt;</c> marker). Bridged from the
/// <c>IAuditRedactionFailureCounter</c> binding registered via
/// <c>AddAuditLogHealthMetricsBridge()</c>.
/// </summary>
void IncrementAuditRedactionFailure();
/// <summary>
/// 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>
/// <param name="snapshot">The audit backlog snapshot.</param>
void UpdateSiteAuditBacklog(SiteAuditBacklogSnapshot snapshot);
/// <summary>
/// Updates the health status for a data connection.
/// </summary>
/// <param name="connectionName">The name of the connection.</param>
/// <param name="health">The connection health status.</param>
void UpdateConnectionHealth(string connectionName, ConnectionHealth health);
/// <summary>
/// Removes a connection from health tracking.
/// </summary>
/// <param name="connectionName">The name of the connection.</param>
void RemoveConnection(string connectionName);
/// <summary>
/// Updates tag resolution metrics for a connection.
/// </summary>
/// <param name="connectionName">The name of the connection.</param>
/// <param name="totalSubscribed">Total number of subscribed tags.</param>
/// <param name="successfullyResolved">Number of successfully resolved tags.</param>
void UpdateTagResolution(string connectionName, int totalSubscribed, int successfullyResolved);
/// <summary>
/// Updates the endpoint for a connection.
/// </summary>
/// <param name="connectionName">The name of the connection.</param>
/// <param name="endpoint">The connection endpoint.</param>
void UpdateConnectionEndpoint(string connectionName, string endpoint);
/// <summary>
/// Updates tag quality metrics for a connection.
/// </summary>
/// <param name="connectionName">The name of the connection.</param>
/// <param name="good">Number of good quality tags.</param>
/// <param name="bad">Number of bad quality tags.</param>
/// <param name="uncertain">Number of uncertain quality tags.</param>
void UpdateTagQuality(string connectionName, int good, int bad, int uncertain);
/// <summary>
/// Sets the store-and-forward buffer depths for all categories.
/// </summary>
/// <param name="depths">Dictionary mapping category names to their buffer depths.</param>
void SetStoreAndForwardDepths(IReadOnlyDictionary<string, int> depths);
/// <summary>
/// Sets the counts of instances in each state.
/// </summary>
/// <param name="deployed">Number of deployed instances.</param>
/// <param name="enabled">Number of enabled instances.</param>
/// <param name="disabled">Number of disabled instances.</param>
void SetInstanceCounts(int deployed, int enabled, int disabled);
/// <summary>
/// Sets the count of parked messages.
/// </summary>
/// <param name="count">The number of parked messages.</param>
void SetParkedMessageCount(int count);
/// <summary>
/// Sets the age (seconds) of the oldest parked store-and-forward message for the
/// next <see cref="CollectReport"/> call; <c>null</c> when no rows are parked.
/// Point-in-time (not reset on collect), refreshed by the parked-count poller in
/// <c>HealthReportSender</c>. Default interface implementation is a no-op so
/// existing test fakes continue to compile without per-fake updates.
/// </summary>
/// <param name="ageSeconds">Age in seconds of the oldest parked row, or <c>null</c> if none are parked.</param>
void SetOldestParkedMessageAgeSeconds(double? ageSeconds)
{
// Default no-op so test fakes do not need to be updated.
}
/// <summary>
/// Replace the latest cumulative
/// site-event-log write-failure count (SQLite error, disk full,
/// bounded-queue overflow drop) used by the next <see cref="CollectReport"/>
/// call. Refreshed periodically by the <c>SiteEventLogFailureCountReporter</c>
/// hosted service. Point-in-time: the value is NOT reset on
/// <see cref="CollectReport"/>; it carries forward until the next poller
/// refresh. Default interface implementation is a no-op so existing test
/// fakes continue to compile without per-fake updates.
/// </summary>
/// <param name="count">The cumulative failed-write count from <c>ISiteEventLogger.FailedWriteCount</c>.</param>
void SetSiteEventLogWriteFailures(long count)
{
// Default no-op so test fakes do not need to be updated. The real
// SiteHealthCollector overrides this with the Interlocked.Exchange store.
}
/// <summary>
/// Replace the latest script-execution-scheduler gauges (queue depth, busy
/// thread count, and age in seconds of the oldest in-flight script) used by
/// the next <see cref="CollectReport"/> call. Refreshed periodically by the
/// <c>ScriptSchedulerStatsReporter</c> hosted service. Point-in-time: the
/// values are NOT reset on <see cref="CollectReport"/>. S2/UA5 — surfaces a
/// saturated or stuck script-execution pool on the site health report.
/// Default interface implementation is a no-op so existing test fakes continue
/// to compile without per-fake updates.
/// </summary>
/// <param name="queueDepth">Script tasks waiting to run.</param>
/// <param name="busyThreads">Worker threads currently executing a script.</param>
/// <param name="oldestBusyAgeSeconds">Age (seconds) of the oldest in-flight script, or <c>null</c> when idle.</param>
void SetScriptSchedulerStats(int queueDepth, int busyThreads, double? oldestBusyAgeSeconds)
{
// Default no-op so test fakes do not need to be updated.
}
/// <summary>
/// Sets the hostname of this node.
/// </summary>
/// <param name="hostname">The node hostname.</param>
void SetNodeHostname(string hostname);
/// <summary>
/// Sets the list of cluster nodes.
/// </summary>
/// <param name="nodes">The list of cluster node statuses.</param>
void SetClusterNodes(IReadOnlyList<Commons.Messages.Health.NodeStatus> nodes);
/// <summary>
/// Sets whether this node is the active node in the cluster.
/// </summary>
/// <param name="isActive">True if this node is active, false otherwise.</param>
void SetActiveNode(bool isActive);
/// <summary>
/// Gets whether this node is the active node in the cluster.
/// </summary>
bool IsActiveNode { get; }
/// <summary>
/// Collects and returns a health report for a site.
/// </summary>
/// <param name="siteId">The site identifier.</param>
/// <returns>A health report for the specified site.</returns>
SiteHealthReport CollectReport(string siteId);
/// <summary>
/// Atomically add back the given per-interval error
/// counts into the collector's accumulators. Called by the report sender
/// when transport delivery of a freshly-collected report fails, so the
/// counts that <see cref="CollectReport"/> already drained roll forward
/// into the next report rather than being silently lost. Concurrent
/// increments arriving between the failed Send and this restore are
/// preserved — <c>Interlocked.Add</c> sums correctly with them. The
/// default interface implementation is a no-op so existing test fakes
/// (the only implementations outside <see cref="SiteHealthCollector"/>)
/// continue to compile without per-fake updates; production callers see
/// the real behaviour via the concrete class.
/// </summary>
/// <param name="scriptErrors">Script error count to add back.</param>
/// <param name="alarmErrors">Alarm evaluation error count to add back.</param>
/// <param name="deadLetters">Dead letter count to add back.</param>
/// <param name="siteAuditWriteFailures">Site audit write failure count to add back.</param>
/// <param name="auditRedactionFailures">Audit redaction failure count to add back.</param>
void AddIntervalCounters(
int scriptErrors,
int alarmErrors,
int deadLetters,
int siteAuditWriteFailures,
int auditRedactionFailures)
{
// Default no-op so test fakes do not need to be updated. The real
// SiteHealthCollector overrides this with the Interlocked.Add restore.
}
}