Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using HealthMonitoring.Domain;
using HealthMonitoring.Reporting;

namespace HealthMonitoring.Tests.Reporting;

public sealed class DashboardModelsTests
{
[Fact]
public void ServiceDashboardRow_preserves_registered_version()
{
var row = new ServiceDashboardRow(
"orders",
"Orders",
"Production",
"2.4.1",
HealthStatus.Healthy,
TimeSpan.FromMilliseconds(20),
99.9,
DateTimeOffset.UtcNow,
null);

Assert.Equal("2.4.1", row.Version);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ else
@foreach (var service in _overview.Services)
{
<a class="service-row" href="/services/@service.ServiceId">
<div><strong>@service.Name</strong><small>@service.Environment</small></div>
<div><strong>@service.Name</strong><small>@service.Environment</small><small class="service-version">Version: @(string.IsNullOrWhiteSpace(service.Version) ? "not reported" : service.Version)</small></div>
<div><StatusBadge Status="@service.Status" /></div>
<div>@(service.ResponseDuration?.TotalMilliseconds.ToString("0") ?? "—") ms</div>
<div>@service.UptimePercent.ToString("0.00")%</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}
else
{
<div class="page-heading"><div><p class="eyebrow">SERVICE DETAIL · @_model.Service.Environment</p><h1>@_model.Service.Name</h1><p class="muted">@(_model.Service.MonitorType == MonitorType.KurrentDb ? "KurrentDB monitor" : _model.Service.HealthUrl.ToString())</p></div><div><a class="button secondary" href="@($"/services/{ServiceId}/dependencies")">Manage dependency links</a> <a class="button secondary" href="/">Back to overview</a></div></div>
<div class="page-heading"><div><p class="eyebrow">SERVICE DETAIL · @_model.Service.Environment</p><h1>@_model.Service.Name</h1><p class="muted">@(_model.Service.MonitorType == MonitorType.KurrentDb ? "KurrentDB monitor" : _model.Service.HealthUrl.ToString())</p><p class="service-version-detail">Version: <strong>@(string.IsNullOrWhiteSpace(_model.Service.Version) ? "not reported" : _model.Service.Version)</strong></p></div><div><a class="button secondary" href="@($"/services/{ServiceId}/dependencies")">Manage dependency links</a> <a class="button secondary" href="/">Back to overview</a></div></div>
<div class="detail-status"><StatusBadge Status="@_model.Summary.Status" /> <span>Last checked @( _model.Summary.LastChecked?.ToLocalTime().ToString("dd MMM, HH:mm:ss") ?? "never")</span></div>
<div class="stat-grid three"><StatCard Label="Uptime (24 hours)" Value="@UptimeText" Class="healthy" /><StatCard Label="Observations" Value="@_model.Observations.Count" Class="neutral" /><StatCard Label="Response" Value="@ResponseText" Class="neutral" /></div>
<section class="panel"><h2>Status timeline</h2><div class="timeline">@foreach (var observation in _model.Observations.OrderBy(item => item.ObservedAtUtc)) { <span class="timeline-segment @observation.Status.ToString().ToLowerInvariant()" title="@observation.ObservedAtUtc.ToLocalTime()"></span> }</div></section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<EditForm Model="_request" OnValidSubmit="RegisterAsync" class="panel form">
<label>Service ID<input @bind="_request.ServiceId" required /></label>
<label>Display name<input @bind="_request.Name" required /></label>
<label>Version<input @bind="_request.Version" placeholder="e.g. 2.4.1" /></label>
<label>Monitor type<select @bind="_request.MonitorType"><option value="HttpHealthEndpoint">ASP.NET health endpoint</option><option value="KurrentDb">KurrentDB</option><option value="SqlServer">SQL Server</option></select></label>
@if (_request.MonitorType is MonitorType.KurrentDb or MonitorType.SqlServer)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
namespace HealthMonitoring.Reporting;

public sealed record DashboardOverview(IReadOnlyList<ServiceDashboardRow> Services, int Healthy, int Degraded, int Unhealthy, int OpenIncidents);
public sealed record ServiceDashboardRow(string ServiceId, string Name, string Environment, HealthStatus Status, TimeSpan? ResponseDuration, double UptimePercent, DateTimeOffset? LastChecked, string? LastError);
public sealed record ServiceDashboardRow(string ServiceId, string Name, string Environment, string? Version, HealthStatus Status, TimeSpan? ResponseDuration, double UptimePercent, DateTimeOffset? LastChecked, string? LastError);
public sealed record ResolvedDependencyLink(string DependencyName, string TargetServiceId, string TargetServiceName);
public sealed record ServiceDetailModel(MonitoredService Service, ServiceDashboardRow Summary, IReadOnlyList<HealthObservation> Observations, IReadOnlyList<ServiceIncident> Incidents, IReadOnlyList<HealthCheckResult> Checks, IReadOnlyList<ResolvedDependencyLink> DependencyLinks);
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ private static ServiceDashboardRow ToRow(MonitoredService service, ServiceStatus
var total = observations.Count;
var healthy = observations.Count(observation => observation.Status == HealthStatus.Healthy);
var uptime = total == 0 ? 0 : healthy * 100d / total;
return new ServiceDashboardRow(service.ServiceId, service.Name, service.Environment, snapshot?.Status ?? HealthStatus.Unknown, snapshot?.LastResponseDuration, uptime, snapshot?.LastObservedAtUtc, snapshot?.LastError);
return new ServiceDashboardRow(service.ServiceId, service.Name, service.Environment, service.Version, snapshot?.Status ?? HealthStatus.Unknown, snapshot?.LastResponseDuration, uptime, snapshot?.LastObservedAtUtc, snapshot?.LastError);
}
}
1 change: 1 addition & 0 deletions HealthMonitoring/HealthMonitoring/wwwroot/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading