merge: observability (register rows 33, 54, 56, 63, 66) — LocalDb backlog KPI history + sustained-threshold badge, honest stream-subscriber gauge rename + real data-connection gauges, central metrics port on the rig, ASPNETCORE_ENVIRONMENT on site containers, import-session rejection counter

This commit is contained in:
Joseph Doherty
2026-08-15 17:56:14 -04:00
38 changed files with 1417 additions and 52 deletions
@@ -443,12 +443,12 @@ public class SiteStreamGrpcServerTests : TestKit
}
[Fact]
public async Task SiteConnectionUpGauge_GoesToOneOnConnect_AndBackToZeroOnCancel()
public async Task SiteStreamSubscribersActiveGauge_GoesToOneOnConnect_AndBackToZeroOnCancel()
{
// Telemetry follow-on: the scadabridge.site.connection.up gauge must read
// Telemetry follow-on: the scadabridge.site.stream.subscribers.active gauge must read
// exactly 1 while a site stream is established and return to 0 once the
// stream terminates on the cancel path — proving SiteConnectionOpened() is
// matched by exactly one SiteConnectionClosed() in the handler's finally.
// stream terminates on the cancel path — proving SiteStreamSubscriberOpened() is
// matched by exactly one SiteStreamSubscriberClosed() in the handler's finally.
var server = CreateServer();
server.SetReady(Sys);
@@ -459,7 +459,7 @@ public class SiteStreamGrpcServerTests : TestKit
listener.InstrumentPublished = (instrument, l) =>
{
if (instrument.Meter.Name == ScadaBridgeTelemetry.MeterName &&
instrument.Name == "scadabridge.site.connection.up")
instrument.Name == "scadabridge.site.stream.subscribers.active")
{
l.EnableMeasurementEvents(instrument);
}
@@ -485,7 +485,7 @@ public class SiteStreamGrpcServerTests : TestKit
// (possibly parallel) tests left behind — read relative so the assertion
// is robust to test interleaving on the process-wide static counter.
//
// SiteConnectionOpened() runs AFTER the _activeStreams insertion that
// SiteStreamSubscriberOpened() runs AFTER the _activeStreams insertion that
// WaitForConditionAsync(ActiveStreamCount == 1) keys off (see
// SiteStreamGrpcServer.SubscribeInstance), so a one-shot ReadGauge() here
// can race the increment under full-suite CPU oversubscription. Poll the
@@ -499,7 +499,7 @@ public class SiteStreamGrpcServerTests : TestKit
// After the cancel path runs the finally, the gauge is balanced back to
// the baseline — no leaked "up" count. Poll here too: the gauge decrement
// and the stream-count drop are independent observations, so under load
// give the finally's SiteConnectionClosed() time to land.
// give the finally's SiteStreamSubscriberClosed() time to land.
AwaitAssert(() => Assert.Equal(baseline, ReadGauge()), TimeSpan.FromSeconds(5));
}
@@ -7,7 +7,7 @@ namespace ZB.MOM.WW.ScadaBridge.Communication.Tests;
/// Telemetry guards for the aggregated live alarm cache (plan #10, Task 6): the
/// active-aggregator observable gauge reflects Started/Stopped, and the reconnect
/// counter increments on each recorded reconnect. Mirrors the MeterListener read
/// pattern used by <c>SiteStreamGrpcServerTests.SiteConnectionUpGauge_*</c>; reads are
/// pattern used by <c>SiteStreamGrpcServerTests.SiteStreamSubscribersActiveGauge_*</c>; reads are
/// relative to a baseline so the process-wide static instruments are robust to any
/// parallel test interleaving.
/// </summary>