The overview kept listing removed and paused instances with their last data and counted them in the totals and alerts. Removed instances now disappear from the overview, Alle fund, /api/v1/instances and /metrics (their history stays for reports and the instance page); paused ones are shown as "Sat på pause" and are left out of the totals, the urgent findings and the alerts (Prometheus gets sqlinsight_instance_paused instead of instance_up = 0). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
97 lines
5.3 KiB
Text
97 lines
5.3 KiB
Text
@page "/"
|
||
@inject InsightRepository Repository
|
||
@inject Display Display
|
||
|
||
<PageTitle>SQLInsight Pro</PageTitle>
|
||
|
||
<h1>Overblik</h1>
|
||
<p class="lead">Status for alle overvågede SQL Server-instanser.</p>
|
||
|
||
@if (_instances.Count == 0)
|
||
{
|
||
<div class="empty">
|
||
<p>Der er endnu ingen data. Tilføj en server under <a href="/opsaetning/instanser">Servere og databaser</a>, og tjek, at SQLInsight Agent kører.</p>
|
||
</div>
|
||
}
|
||
else
|
||
{
|
||
<PrivilegeAlert Findings="_active" ShowInstance="true" />
|
||
|
||
<div class="kpis">
|
||
<div class="kpi"><span class="kpi-icon"><Icon Name="servers" /></span><div><strong>@_monitored.Count</strong><span>instanser@(_paused > 0 ? $" (+{_paused} på pause)" : string.Empty)</span></div></div>
|
||
<div class="kpi sev-critical"><span class="kpi-icon"><Icon Name="alert" /></span><div><strong>@_monitored.Sum(i => i.Critical)</strong><span>kritiske fund</span></div></div>
|
||
<div class="kpi sev-high"><span class="kpi-icon"><Icon Name="alert" /></span><div><strong>@_monitored.Sum(i => i.High)</strong><span>høje fund</span></div></div>
|
||
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="unplug" /></span><div><strong>@_monitored.Count(i => i.IsFailing)</strong><span>kan ikke nås</span></div></div>
|
||
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="gauge" /></span><div><strong>@_monitored.Sum(i => i.NotMeasurable)</strong><span>regler ikke målbare</span></div></div>
|
||
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="list" /></span><div><strong>@_monitored.Sum(i => i.ManualChecks)</strong><span>skal tjekkes manuelt</span></div></div>
|
||
</div>
|
||
|
||
<section class="card">
|
||
<div class="card-head"><h2>Instanser</h2><span class="muted">sorteret efter alvor</span></div>
|
||
<table class="instances">
|
||
<thead>
|
||
<tr><th>Status</th><th>Instans</th><th>Version</th><th>Fund</th><th>Ikke målbar</th><th>Sidst set</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach (var i in _instances.OrderBy(i => i.Paused).ThenByDescending(i => i.IsFailing).ThenByDescending(i => i.WorstSeverity ?? (Severity)(-1)).ThenBy(i => i.Name))
|
||
{
|
||
<tr class="@(i.Paused ? "paused" : string.Empty)">
|
||
<td>
|
||
@if (i.Paused)
|
||
{
|
||
<span class="badge sev-info" title="Overvågningen er sat på pause under Servere og databaser. Der kommer ingen nye fund eller alarmer, og tallene tæller ikke med i overblikket.">Sat på pause</span>
|
||
}
|
||
else if (i.IsFailing)
|
||
{
|
||
<span class="badge sev-critical" title="@i.LastError">Fejler</span>
|
||
}
|
||
else
|
||
{
|
||
<SeverityBadge Severity="i.WorstSeverity" />
|
||
}
|
||
</td>
|
||
<td><a href="/instanser/@Uri.EscapeDataString(i.Name)"><strong>@i.Name</strong></a><div class="muted">@i.ServerName</div></td>
|
||
<td>@(i.ProductVersion is null ? "–" : Display.Release(i.ProductVersion, i.EngineEdition))<div class="muted">@i.ProductVersion @i.ProductLevel @i.ProductUpdateLevel</div></td>
|
||
<td><div class="counts">
|
||
@if (i.Paused)
|
||
{
|
||
<span class="muted">sidste data før pausen</span>
|
||
}
|
||
@if (i.Critical > 0) { <SeverityBadge Severity="Severity.Critical" Count="i.Critical" /> }
|
||
@if (i.High > 0) { <SeverityBadge Severity="Severity.High" Count="i.High" /> }
|
||
@if (i.Medium > 0) { <SeverityBadge Severity="Severity.Medium" Count="i.Medium" /> }
|
||
@if (i.Low > 0) { <SeverityBadge Severity="Severity.Low" Count="i.Low" /> }
|
||
</div></td>
|
||
<td>@i.NotMeasurable</td>
|
||
<td title="@Display.Time(i.LastSeenAt)">@Display.Ago(i.LastSeenAt)</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<div class="card-head"><h2>Kritiske og høje fund</h2><a href="/fund">Se alle fund</a></div>
|
||
<FindingList Findings="_urgent" ShowInstance="true" Empty="Ingen kritiske eller høje fund." />
|
||
</section>
|
||
}
|
||
|
||
@code {
|
||
private IReadOnlyList<InstanceOverview> _instances = [];
|
||
private IReadOnlyList<InstanceOverview> _monitored = [];
|
||
private int _paused;
|
||
private IReadOnlyList<StoredFinding> _active = [];
|
||
private IReadOnlyList<StoredFinding> _urgent = [];
|
||
|
||
protected override async Task OnInitializedAsync()
|
||
{
|
||
// Removed instances are left out (their history stays for reports); paused ones are shown, marked, but do not
|
||
// count in the totals, the urgent findings or the privilege alert.
|
||
_instances = (await Repository.GetInstancesAsync()).Where(i => !i.Removed).ToList();
|
||
_monitored = _instances.Where(i => i.IsMonitored).ToList();
|
||
_paused = _instances.Count(i => i.Paused);
|
||
var monitoredIds = _monitored.Select(i => i.InstanceId).ToHashSet();
|
||
_active = (await Repository.GetActiveFindingsAsync()).Where(f => monitoredIds.Contains(f.InstanceId)).ToList();
|
||
_urgent = _active.Where(f => f.Severity >= Severity.High).ToList();
|
||
}
|
||
}
|