< Summary

Information
Class: Elsa.Diagnostics.StructuredLogs.Dashboard.StructuredLogsDashboardContributor
Assembly: Elsa.Diagnostics.StructuredLogs.Dashboard
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Diagnostics.StructuredLogs.Dashboard/Dashboard/StructuredLogsDashboardContributor.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 59
Coverable lines: 59
Total lines: 90
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
get_Id()100%210%
get_Order()100%210%
GetOverviewAsync()100%210%
GetFindingsAsync()0%110100%
GetSummaryAsync()100%210%
Finding(...)100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Diagnostics.StructuredLogs.Dashboard/Dashboard/StructuredLogsDashboardContributor.cs

#LineLine coverage
 1using Elsa.Dashboard.Abstractions.Contracts;
 2using Elsa.Dashboard.Abstractions.Models;
 3using Elsa.Diagnostics.StructuredLogs.Contracts;
 4using Elsa.Diagnostics.StructuredLogs.Models;
 5
 6namespace Elsa.Diagnostics.StructuredLogs.Dashboard;
 7
 08public class StructuredLogsDashboardContributor(
 09    IStructuredLogProvider provider,
 010    IEnumerable<IStructuredLogStorageDiagnostics> storageDiagnostics) : IDashboardContributor
 11{
 012    public string Id => "diagnostics.structured-logs";
 13
 014    public int Order => 300;
 15
 16    public async ValueTask<DashboardOverviewContribution?> GetOverviewAsync(DashboardContext context)
 17    {
 018        var summary = await GetSummaryAsync(context.Range, context.CancellationToken);
 019        return new()
 020        {
 021            Diagnostics = new()
 022            {
 023                StructuredLogs = summary
 024            }
 025        };
 026    }
 27
 28    public async ValueTask<IReadOnlyCollection<DashboardFinding>> GetFindingsAsync(DashboardContext context)
 29    {
 030        var summary = await GetSummaryAsync(context.Range, context.CancellationToken);
 031        var findings = new List<DashboardFinding>();
 32
 033        if (summary.Capability.Status == DashboardCapabilityStatus.Unauthorized.Status)
 034            findings.Add(Finding("structured-log-unauthorized", DashboardFindingSeverity.Warning, "Structured log dashbo
 035        else if (summary.Capability.Status == DashboardCapabilityStatus.Unavailable.Status)
 036            findings.Add(Finding("structured-log-unavailable", DashboardFindingSeverity.Warning, "Structured log dashboa
 37
 038        if (summary.StaleSourceCount > 0)
 039            findings.Add(Finding("structured-log-stale-sources", DashboardFindingSeverity.Warning, $"{summary.StaleSourc
 040        if (summary.DroppedWriteCount > 0)
 041            findings.Add(Finding("structured-log-dropped-writes", DashboardFindingSeverity.Error, "Structured log storag
 042        if (summary.RecentErrorOrCriticalCount > 0)
 043            findings.Add(Finding("structured-log-errors", DashboardFindingSeverity.Error, $"{summary.RecentErrorOrCritic
 44
 045        return findings;
 046    }
 47
 48    private async Task<DashboardStructuredLogSummary> GetSummaryAsync(DashboardRange range, CancellationToken cancellati
 49    {
 50        try
 51        {
 052            var sources = await provider.ListSourcesAsync(cancellationToken);
 053            var recentErrors = await provider.GetRecentAsync(new()
 054            {
 055                Levels = [StructuredLogLevel.Error, StructuredLogLevel.Critical],
 056                From = range.From,
 057                To = range.To,
 058                Take = 1000
 059            }, cancellationToken);
 60
 061            return new()
 062            {
 063                Capability = DashboardCapabilityStatus.Available,
 064                SourceCount = sources.Count,
 065                StaleSourceCount = sources.Count(x => x.Status == StructuredLogSourceStatus.Stale || x.Status == Structu
 066                RecentErrorOrCriticalCount = recentErrors.Items.Count,
 067                DroppedWriteCount = storageDiagnostics.Aggregate(0L, (total, x) => checked(total + x.DroppedWriteCount))
 068                DroppedEventCount = recentErrors.DroppedEvents
 069            };
 70        }
 071        catch (UnauthorizedAccessException)
 72        {
 073            return new() { Capability = new(DashboardCapabilityStatus.Unauthorized.Status, "No access to structured logs
 74        }
 075        catch (Exception e) when (e is not OperationCanceledException)
 76        {
 077            return new() { Capability = new(DashboardCapabilityStatus.Unavailable.Status, "Structured log summary is una
 78        }
 079    }
 80
 081    private static DashboardFinding Finding(string id, string severity, string message, string? targetKind, string? targ
 082    {
 083        Id = id,
 084        Severity = severity,
 085        Message = message,
 086        TargetKind = targetKind,
 087        Target = target,
 088        Priority = priority
 089    };
 90}