Skip to content

Commit 7edc1c9

Browse files
feat: merge main into release/2.0.0
Merge the latest changes from main into release/2.0.0.
2 parents 85757e1 + 1d8994b commit 7edc1c9

4 files changed

Lines changed: 161 additions & 6 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212

1313
steps:
1414
- name: Checkout
15-
uses: actions/checkout@v6
15+
uses: actions/checkout@v7
1616

1717
- name: Setup .NET
1818
uses: actions/setup-dotnet@v5

DebugProbe.AspNetCore/Assets/css/debugprobe.css

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* =========================
1+
/* =========================
22
Base
33
========================= */
44

@@ -1128,3 +1128,86 @@ pre {
11281128
background: #4a1717;
11291129
color: #ff8a8a !important;
11301130
}
1131+
1132+
/* =========================
1133+
Waterfall View
1134+
========================= */
1135+
1136+
.waterfall-container {
1137+
margin-bottom: 12px;
1138+
}
1139+
1140+
.waterfall-container .trace-card-main {
1141+
padding: 12px 14px;
1142+
}
1143+
1144+
.waterfall-container .trace-card-header {
1145+
padding: 0 0 12px 0;
1146+
}
1147+
1148+
.waterfall-container .trace-dot {
1149+
background: #9b51e0;
1150+
}
1151+
1152+
.waterfall-row {
1153+
display: flex;
1154+
align-items: center;
1155+
gap: 12px;
1156+
margin-bottom: 8px;
1157+
}
1158+
1159+
.waterfall-row:last-child {
1160+
margin-bottom: 0;
1161+
}
1162+
1163+
.wf-label {
1164+
flex: 0 0 200px;
1165+
width: 200px;
1166+
min-width: 200px;
1167+
overflow: hidden;
1168+
text-overflow: ellipsis;
1169+
white-space: nowrap;
1170+
font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
1171+
font-size: 12px;
1172+
color: #4b5563;
1173+
}
1174+
1175+
.wf-track {
1176+
flex: 1;
1177+
position: relative;
1178+
height: 20px;
1179+
background: #f3f4f6;
1180+
border-radius: 4px;
1181+
}
1182+
1183+
.wf-bar {
1184+
position: absolute;
1185+
top: 0;
1186+
bottom: 0;
1187+
display: flex;
1188+
align-items: center;
1189+
justify-content: center;
1190+
background: #9b51e0;
1191+
color: #fff;
1192+
font-size: 10px;
1193+
font-weight: bold;
1194+
border-radius: 3px;
1195+
white-space: nowrap;
1196+
overflow: hidden;
1197+
text-overflow: ellipsis;
1198+
padding: 0 4px;
1199+
box-sizing: border-box;
1200+
}
1201+
1202+
.wf-bar--error {
1203+
background: #e74c3c;
1204+
}
1205+
1206+
@media (max-width: 640px) {
1207+
.wf-label {
1208+
flex: 0 0 100px;
1209+
width: 100px;
1210+
min-width: 100px;
1211+
}
1212+
}
1213+

DebugProbe.AspNetCore/DebugProbe.AspNetCore.csproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<NoWarn>1591</NoWarn>
99

1010
<PackageId>DebugProbe.AspNetCore</PackageId>
11-
<Version>1.6.5</Version>
11+
<Version>1.6.6</Version>
1212

1313
<Authors>Georgi Hristov</Authors>
1414

@@ -17,7 +17,14 @@
1717
<PackageTags>aspnetcore;debugging;http;middleware;diagnostics;tracing;observability;api-debugging;developer-tools;trace-comparison;environment-comparison</PackageTags>
1818

1919
<PackageReleaseNotes>
20-
Fixes response size tracking to report the actual number of bytes sent to the client instead of the captured body size. Adds validation for MaxBodyCaptureSizeKb to reject negative values while allowing 0 to disable body capture. Updates Microsoft.AspNetCore.TestHost to 8.0.28 and xunit.runner.visualstudio to 3.1.5.
20+
## What's New
21+
22+
- Added configurable RoutePrefix support for customizing DebugProbe endpoints.
23+
- Fixed endpoint mapping to respect production UI configuration.
24+
- Fixed outgoing HTTP body capture stream preservation.
25+
- Fixed outgoing HTTP body capture to avoid reading beyond the configured limit.
26+
27+
Thanks to @DevSars24 for the community contributions.
2128
</PackageReleaseNotes>
2229

2330
<PackageIcon>icon.png</PackageIcon>

DebugProbe.AspNetCore/Internal/Rendering/HtmlRenderer.cs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,12 @@ public static string RenderDetailsPage(DebugEntry x, DebugEnvironment e, string
9999
BuildPayloadSection("Body", res, "body")
100100
]);
101101

102+
var waterfall = BuildWaterfallSection(x);
103+
102104
var outgoingRequests = string.Join("", x.OutgoingRequests.Select(BuildOutgoingRequestCard));
103105

106+
var combinedOutgoing = waterfall + outgoingRequests;
107+
104108
var content = EmbeddedResources.Details
105109
.Replace("{{method}}", Encode(x.Method))
106110
.Replace("{{path}}", Encode(pathWithQuery))
@@ -124,9 +128,9 @@ public static string RenderDetailsPage(DebugEntry x, DebugEnvironment e, string
124128
.Replace("{{dateFormat}}", e.DateFormat ?? "")
125129
.Replace("{{assemblyVersion}}", Encode(e.AssemblyVersion))
126130
.Replace("{{outgoingRequests}}",
127-
string.IsNullOrWhiteSpace(outgoingRequests)
131+
string.IsNullOrWhiteSpace(combinedOutgoing)
128132
? "<div class='empty-state trace-empty'>No outgoing dependency calls</div>"
129-
: outgoingRequests)
133+
: combinedOutgoing)
130134
.Replace("{{incomingRequest}}", incomingRequest)
131135
.Replace("{{incomingResponse}}", incomingResponse);
132136

@@ -188,6 +192,67 @@ private static string BuildOutgoingRequestCard(DebugOutgoingRequest request)
188192
details: details);
189193
}
190194

195+
private static string BuildWaterfallSection(DebugEntry entry)
196+
{
197+
const double MinPercent = 0.0;
198+
const double MaxPercent = 100.0;
199+
200+
if (entry.OutgoingRequests.Count == 0)
201+
{
202+
return string.Empty;
203+
}
204+
205+
var totalSpan = (double)entry.DurationMs;
206+
if (totalSpan <= 0)
207+
{
208+
totalSpan = 1.0;
209+
}
210+
211+
var rowsHtml = new List<string>();
212+
213+
foreach (var outgoing in entry.OutgoingRequests)
214+
{
215+
var startOffsetMs = (outgoing.TimestampUtc - entry.Timestamp.UtcDateTime).TotalMilliseconds - outgoing.DurationMs;
216+
217+
var left = Math.Clamp((startOffsetMs / totalSpan) * MaxPercent, MinPercent, MaxPercent);
218+
var width = Math.Clamp(((double)outgoing.DurationMs / totalSpan) * MaxPercent, MinPercent, MaxPercent);
219+
220+
var leftStr = left.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture);
221+
var widthStr = width.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture);
222+
223+
var barClass = "wf-bar";
224+
if (!outgoing.IsSuccessStatusCode || !string.IsNullOrWhiteSpace(outgoing.Exception))
225+
{
226+
barClass += " wf-bar--error";
227+
}
228+
229+
var displayLabel = GetDisplayTarget(outgoing.Url);
230+
231+
rowsHtml.Add($@"
232+
<div class=""waterfall-row"">
233+
<span class=""wf-label"" title=""{Encode(outgoing.Url)}"">{Encode(displayLabel)}</span>
234+
<div class=""wf-track"">
235+
<div class=""{barClass}"" style=""left: {leftStr}%; width: {widthStr}%;"">{outgoing.DurationMs} ms</div>
236+
</div>
237+
</div>");
238+
}
239+
240+
return $@"
241+
<article class=""trace-card waterfall-container"">
242+
<div class=""trace-card-main"">
243+
<div class=""trace-card-header"">
244+
<div class=""trace-card-title"">
245+
<span class=""trace-dot"" aria-hidden=""true""></span>
246+
<span class=""trace-label"">Waterfall Timeline</span>
247+
</div>
248+
</div>
249+
<div class=""trace-details"">
250+
{string.Join("", rowsHtml)}
251+
</div>
252+
</div>
253+
</article>";
254+
}
255+
191256
private static string BuildTraceCard(string label, string method, string target, string classes, IEnumerable<string> details, int? statusCode = null, string? statusText = null, long? durationMs = null)
192257
{
193258
var targetHost = GetDisplayTarget(target);

0 commit comments

Comments
 (0)