From 1fae6355b48457e690e32ae3f3ff3a423d3f68a4 Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Wed, 23 Oct 2024 09:58:48 -0700 Subject: [PATCH] Add uptime column to the dashboard Signed-off-by: Dave Thaler --- OrcanodeMonitor/Pages/Index.cshtml | 4 +++ OrcanodeMonitor/Pages/Index.cshtml.cs | 50 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/OrcanodeMonitor/Pages/Index.cshtml b/OrcanodeMonitor/Pages/Index.cshtml index 4daae6a..0dc3513 100644 --- a/OrcanodeMonitor/Pages/Index.cshtml +++ b/OrcanodeMonitor/Pages/Index.cshtml @@ -18,6 +18,7 @@ SD Card Util. Mezmo S3 Stream + Up% Orcasound OrcaHello @@ -70,6 +71,9 @@ } + + @Model.GetUptimePercentage(item)% + @if (item.OrcasoundStatus == Models.OrcanodeOnlineStatus.Absent) { diff --git a/OrcanodeMonitor/Pages/Index.cshtml.cs b/OrcanodeMonitor/Pages/Index.cshtml.cs index 3206775..2909393 100644 --- a/OrcanodeMonitor/Pages/Index.cshtml.cs +++ b/OrcanodeMonitor/Pages/Index.cshtml.cs @@ -14,10 +14,12 @@ public class IndexModel : PageModel { private OrcanodeMonitorContext _databaseContext; private readonly ILogger _logger; + private List _events; private List _nodes; public List Nodes => _nodes; private const int _maxEventCountToDisplay = 20; public List RecentEvents => Fetcher.GetEvents(_databaseContext, _maxEventCountToDisplay); + private TimeSpan _uptimeEvaluationPeriod = TimeSpan.FromDays(7); // 1 week. public IndexModel(OrcanodeMonitorContext context, ILogger logger) { @@ -92,6 +94,49 @@ private string GetTextColor(OrcanodeOnlineStatus status) public string NodeOrcasoundTextColor(Orcanode node) => GetTextColor(node.OrcasoundStatus); + public int GetUptimePercentage(Orcanode node) + { + if (_events == null) + { + return 0; + } + + TimeSpan up = TimeSpan.Zero; + TimeSpan down = TimeSpan.Zero; + DateTime start = DateTime.UtcNow - _uptimeEvaluationPeriod; + string lastValue = string.Empty; + + // Compute uptime percentage by looking at OrcanodeEvents over the past week. + foreach (OrcanodeEvent e in _events.Where(e => (e.Orcanode == node))) + { + if (DateTime.UtcNow - e.DateTimeUtc >= _uptimeEvaluationPeriod) { + // More than a week old. + lastValue = e.Value; + continue; + } + DateTime current = e.DateTimeUtc; + if (lastValue == "up") + { + up += (current - start); + } + else + { + down += (current - start); + } + start = current; + lastValue = e.Value; + } + if (lastValue == "up") + { + up += DateTime.UtcNow - start; + } else + { + down += DateTime.UtcNow - start; + } + + return (int)((100.0 * up) / _uptimeEvaluationPeriod + 0.5); + } + public string NodeDataplicityUpgradeColor(Orcanode node) { OrcanodeUpgradeStatus status = node.DataplicityUpgradeStatus; @@ -104,6 +149,7 @@ public string NodeDataplicityUpgradeColor(Orcanode node) public async Task OnGetAsync() { + // Fetch nodes for display. var nodes = await _databaseContext.Orcanodes.ToListAsync(); _nodes = nodes.Where(n => ((n.DataplicityConnectionStatus != OrcanodeOnlineStatus.Absent) || (n.OrcasoundStatus != OrcanodeOnlineStatus.Absent) || @@ -112,6 +158,10 @@ public async Task OnGetAsync() (n.OrcasoundHost != "dev.orcasound.net")) .OrderBy(n => n.DisplayName) .ToList(); + + // Fetch events for uptime computation. + var events = await _databaseContext.OrcanodeEvents.ToListAsync(); + _events = events.Where(e => e.Type == "hydrophone stream").ToList(); } } }