< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Health.HealthReportTextFormatter
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Health/HealthReportTextFormatter.cs
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
94%
Covered lines: 35
Uncovered lines: 2
Coverable lines: 37
Total lines: 79
Line coverage: 94.5%
Branch coverage
88%
Covered branches: 32
Total branches: 36
Branch coverage: 88.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 10/13/2025 - 16:52:37 Line coverage: 83.7% (31/37) Branch coverage: 63.8% (23/36) Total lines: 79 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e11/19/2025 - 02:25:56 Line coverage: 94.5% (35/37) Branch coverage: 88.8% (32/36) Total lines: 79 Tag: Kestrun/Kestrun@98ff905e5605a920343154665980a71211a03c6d 10/13/2025 - 16:52:37 Line coverage: 83.7% (31/37) Branch coverage: 63.8% (23/36) Total lines: 79 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e11/19/2025 - 02:25:56 Line coverage: 94.5% (35/37) Branch coverage: 88.8% (32/36) Total lines: 79 Tag: Kestrun/Kestrun@98ff905e5605a920343154665980a71211a03c6d

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Format(...)100%1818100%
RenderValue(...)75%131280%
Escape(...)100%11100%
FormatDuration(...)83.33%66100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Health/HealthReportTextFormatter.cs

#LineLine coverage
 1using System.Text;
 2
 3namespace Kestrun.Health;
 4
 5/// <summary>
 6/// Produces a concise, human-readable text representation of a <see cref="HealthReport"/>.
 7/// Intended for terminals, logs, or lightweight probes where structured formats (JSON/YAML/XML)
 8/// are unnecessary.
 9/// </summary>
 10public static class HealthReportTextFormatter
 11{
 12    /// <summary>
 13    /// Formats a <see cref="HealthReport"/> into a concise plain text representation. Includes probe data when <paramre
 14    /// </summary>
 15    /// <param name="report">The health report to format.</param>
 16    /// <param name="includeData">When true (default) emits per-probe data key/value lines.</param>
 17    /// <returns>A multi-line string suitable for console or log output.</returns>
 18    public static string Format(HealthReport report, bool includeData = true)
 19    {
 1720        ArgumentNullException.ThrowIfNull(report);
 1621        var sb = new StringBuilder();
 1622        _ = sb.AppendLine($"Status: {report.StatusText}");
 1623        _ = sb.AppendLine($"GeneratedAt: {report.GeneratedAt:O}");
 1624        var s = report.Summary;
 1625        _ = sb.AppendLine($"Summary: total={s.Total} healthy={s.Healthy} degraded={s.Degraded} unhealthy={s.Unhealthy}")
 1626        if (report.AppliedTags is { Count: > 0 })
 27        {
 128            _ = sb.AppendLine($"Tags: {string.Join(",", report.AppliedTags)}");
 29        }
 1630        _ = sb.AppendLine("Probes:");
 7031        foreach (var p in report.Probes)
 32        {
 1933            _ = sb.Append("  - ");
 1934            _ = sb.Append($"name={p.Name} status={p.StatusText} duration={FormatDuration(p.Duration)}");
 1935            if (!string.IsNullOrWhiteSpace(p.Description))
 36            {
 1937                _ = sb.Append($" desc=\"{Escape(p.Description)}\"");
 38            }
 1939            if (!string.IsNullOrWhiteSpace(p.Error))
 40            {
 241                _ = sb.Append($" error=\"{Escape(p.Error)}\"");
 42            }
 1943            _ = sb.AppendLine();
 1944            if (includeData && p.Data is { Count: > 0 })
 45            {
 3446                foreach (var kvp in p.Data)
 47                {
 1048                    _ = sb.AppendLine($"      {kvp.Key}={RenderValue(kvp.Value)}");
 49                }
 50            }
 51        }
 1652        return sb.ToString();
 53    }
 54
 55    private static string RenderValue(object? value)
 56    {
 1057        return value is null
 1058            ? "<null>"
 1059            : value switch
 1060            {
 261                string s => '"' + Escape(s) + '"',
 162                DateTime dt => dt.ToString("O"),
 063                DateTimeOffset dto => dto.ToString("O"),
 064                TimeSpan ts => ts.ToString(),
 665                _ => value.ToString() ?? string.Empty
 1066            };
 67    }
 68
 2369    private static string Escape(string input) => input.Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", "\\r");
 70
 71    private static string FormatDuration(TimeSpan duration)
 72    {
 1973        return duration.TotalMilliseconds < 1
 1974            ? "<1ms"
 1975            : duration.TotalMilliseconds < 1000
 1976            ? ((int)duration.TotalMilliseconds) + "ms"
 1977            : duration.TotalSeconds < 60 ? duration.TotalSeconds.ToString("0.###") + "s" : duration.ToString();
 78    }
 79}