Skip to content

Commit 8aef49d

Browse files
feat(ui): add request metrics overview cards
1 parent 6c11c4c commit 8aef49d

3 files changed

Lines changed: 82 additions & 1 deletion

File tree

DebugProbe.AspNetCore/Assets/css/debugprobe.css

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,39 @@ h4 {
7777
margin-bottom: 14px;
7878
}
7979

80+
.stats-bar {
81+
display: grid;
82+
grid-template-columns: repeat(4, minmax(150px, 1fr));
83+
gap: 10px;
84+
margin-bottom: 14px;
85+
}
86+
87+
.stat-tile {
88+
display: flex;
89+
align-items: center;
90+
justify-content: center;
91+
gap: 8px;
92+
min-height: 52px;
93+
padding: 0 16px;
94+
background: #fff;
95+
border: 1px solid #e9e9e9;
96+
border-radius: 8px;
97+
text-align: center;
98+
}
99+
100+
.stat-tile strong {
101+
color: #1f2937;
102+
font-size: 22px;
103+
line-height: 1;
104+
}
105+
106+
.stat-tile span {
107+
color: #666;
108+
font-size: 13px;
109+
font-weight: 700;
110+
text-transform: uppercase;
111+
}
112+
80113
.filters input,
81114
.filters select {
82115
min-height: 36px;
@@ -325,6 +358,10 @@ tbody tr:last-child td {
325358
grid-template-columns: 1fr;
326359
}
327360

361+
.stats-bar {
362+
grid-template-columns: repeat(2, minmax(0, 1fr));
363+
}
364+
328365
.payload-group {
329366
padding: 14px;
330367
}

DebugProbe.AspNetCore/Assets/html/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@ <h2>Requests</h2>
66
</div>
77
</div>
88

9+
<div class="stats-bar" aria-label="Request summary">
10+
<div class="stat-tile">
11+
<strong>{{total_requests}}</strong>
12+
<span>Requests</span>
13+
</div>
14+
<div class="stat-tile">
15+
<strong>{{avg_response_time}}</strong>
16+
<span>Avg</span>
17+
</div>
18+
<div class="stat-tile">
19+
<strong>{{slow_requests}}</strong>
20+
<span>Slow</span>
21+
</div>
22+
<div class="stat-tile">
23+
<strong>{{error_rate}}</strong>
24+
<span>Errors</span>
25+
</div>
26+
</div>
27+
928
<div class="filters" aria-label="Request filters">
1029
<input id="requestSearch" type="search" placeholder="Search path, method, status, or trace id" autocomplete="off" />
1130
<select id="methodFilter" aria-label="Filter by method">

DebugProbe.AspNetCore/Internal/Rendering/HtmlRenderer.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public static string BuildLayout(string content)
2424

2525
public static string RenderIndexPage(List<DebugEntry> items)
2626
{
27+
const int slowRequestThresholdMs = 1000;
28+
2729
var rows = string.Join("", items.Select(x => $@"
2830
<tr data-url=""/debug/{Encode(x.Id)}""
2931
data-method=""{Encode(x.Method)}""
@@ -48,10 +50,23 @@ public static string RenderIndexPage(List<DebugEntry> items)
4850
.OrderBy(method => method, StringComparer.OrdinalIgnoreCase)
4951
.Select(method => $@"<option value=""{Encode(method)}"">{Encode(method)}</option>"));
5052

53+
var totalRequests = items.Count;
54+
var averageResponseMs = totalRequests == 0
55+
? 0
56+
: (int)Math.Round(items.Average(x => x.DurationMs));
57+
var slowRequests = items.Count(x => x.DurationMs >= slowRequestThresholdMs);
58+
var errorRate = totalRequests == 0
59+
? 0
60+
: items.Count(x => x.StatusCode >= 400) * 100d / totalRequests;
61+
5162
return BuildLayout(EmbeddedResources.Index
5263
.Replace("{{rows}}", rows)
5364
.Replace("{{total_count}}", items.Count.ToString())
54-
.Replace("{{method_options}}", methodOptions));
65+
.Replace("{{method_options}}", methodOptions)
66+
.Replace("{{total_requests}}", FormatCompactNumber(totalRequests))
67+
.Replace("{{avg_response_time}}", $"{averageResponseMs} ms")
68+
.Replace("{{slow_requests}}", FormatCompactNumber(slowRequests))
69+
.Replace("{{error_rate}}", $"{errorRate:0.#}%"));
5570
}
5671

5772
public static string RenderDetailsPage(DebugEntry x, DebugEnvironment e, string req, string res)
@@ -132,4 +147,14 @@ private static string GetResponseGroupClass(int statusCode)
132147
return statusCode >= 400 ? "response-error" : "";
133148
}
134149

150+
private static string FormatCompactNumber(int value)
151+
{
152+
return value switch
153+
{
154+
>= 1_000_000 => $"{value / 1_000_000d:0.#}M",
155+
>= 1_000 => $"{value / 1_000d:0.#}K",
156+
_ => value.ToString()
157+
};
158+
}
159+
135160
}

0 commit comments

Comments
 (0)