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
17 changes: 17 additions & 0 deletions DebugProbe.AspNetCore/Internal/HtmlRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,27 @@ public static string RenderDetailsPage(DebugEntry x, string req, string res)
.Replace("{{path}}", Encode(pathWithQuery))
.Replace("{{status}}", x.StatusCode.ToString())
.Replace("{{tradeId}}", x.Id.ToString())

.Replace("{{time}}", x.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"))
.Replace("{{local}}", x.Timestamp.ToLocalTime().ToString("HH:mm:ss"))

.Replace("{{durationMs}}", x.DurationMs.ToString())
.Replace("{{requestSize}}", x.RequestSize.ToString())
.Replace("{{responseSize}}", x.ResponseSize.ToString())

.Replace("{{env}}", Encode(x.Environment))
.Replace("{{culture}}", Encode(x.Culture))

.Replace("{{machineName}}", Encode(x.MachineName))
.Replace("{{timeZone}}", Encode(x.TimeZone))
.Replace("{{decimalSeparator}}", Encode(x.DecimalSeparator))
.Replace("{{dateFormat}}", x.DateFormat ?? "")
.Replace("{{assemblyVersion}}", Encode(x.AssemblyVersion))





.Replace("{{requestUrl}}", Encode(string.IsNullOrEmpty(x.RequestUrl) ? "(empty)" : x.RequestUrl))
.Replace("{{request}}", Encode(string.IsNullOrEmpty(req) ? "(empty)" : req))
.Replace("{{response}}", Encode(string.IsNullOrEmpty(res) ? "(empty)" : res))
Expand Down
45 changes: 37 additions & 8 deletions DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Globalization;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Text;
using DebugProbe.AspNetCore.Internal;
using DebugProbe.AspNetCore.Models;
using DebugProbe.AspNetCore.Storage;
Expand Down Expand Up @@ -39,35 +42,61 @@ public async Task Invoke(HttpContext context, DebugEntryStore store)
using var ms = new MemoryStream();
context.Response.Body = ms;

var started = Stopwatch.StartNew();

await _next(context);

started.Stop();

ms.Position = 0;
var responseBody = await new StreamReader(ms).ReadToEndAsync();
ms.Position = 0;
await ms.CopyToAsync(originalBody);

var shortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
var index = shortDatePattern.LastIndexOf('y');
var dataFormat = index >= 0 ? shortDatePattern[..(index + 1)] : shortDatePattern;

store.Add(new DebugEntry
{
Id = Guid.NewGuid().ToString(),

Path = context.Request.Path,
// Environment
Environment = EnvironmentUtils.TryGetEnvironment(),
MachineName = Environment.MachineName,
AssemblyVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(),
TimeZone = TimeZoneInfo.Local.DisplayName,
Culture = CultureInfo.CurrentCulture.Name,
DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator,
DateFormat = dataFormat,

// Overview
Method = context.Request.Method,
StatusCode = context.Response.StatusCode,
Path = context.Request.Path,
Query = context.Request.QueryString.ToString(),
StatusCode = context.Response.StatusCode,
RequestTimeUtc = DateTime.UtcNow,
DurationMs = started.ElapsedMilliseconds,
RequestSize = Encoding.UTF8.GetByteCount(requestBody),
ResponseSize = Encoding.UTF8.GetByteCount(responseBody),

// Request
RequestUrl = $"{context.Request.Scheme}://{context.Request.Host}" +
$"{context.Request.Path}{context.Request.QueryString}",

RequestBody = Trim(requestBody),


// Response
ResponseBody = Trim(responseBody),


// Headers
Headers = context.Request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString()),
Timestamp = DateTime.UtcNow,

Environment = EnvironmentUtils.TryGetEnvironment(),
Culture = CultureInfo.CurrentCulture.Name,
RequestTimeUtc = DateTime.UtcNow,

// Other
Timestamp = DateTime.UtcNow,

});
}

Expand Down
19 changes: 14 additions & 5 deletions DebugProbe.AspNetCore/Models/DebugEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,29 @@ public class DebugEntry
public string? Query { get; set; }
public string? RequestUrl { get; set; }
public string RequestBody { get; set; } = default!;
public DateTime RequestTimeUtc { get; set; }

public DateTimeOffset RequestTimeUtc { get; set; }
public long RequestSize { get; set; }
public long DurationMs { get; set; }

// Response
public int StatusCode { get; set; }
public long ResponseSize { get; set; }
public string ResponseBody { get; set; } = default!;


// Context
// Environment
public string Environment { get; set; } = default!;
public string Culture { get; set; } = default!;
public string? UiCulture { get; set; }

public string? MachineName { get; set; }
public string? AssemblyVersion { get; set; }
public string? TimeZone { get; set; }
public string? DecimalSeparator { get; set; }
public string? DateFormat { get; set; }

// Headers
public Dictionary<string, string> Headers { get; set; } = new();

public DateTime Timestamp { get; set; }
// Metadata
public DateTimeOffset Timestamp { get; set; }
}
102 changes: 102 additions & 0 deletions DebugProbe.AspNetCore/Resources/css/debugprobe.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,54 @@ a {
opacity: 0.9;
}

/* =========================
Details
========================= */

.details-grid {
align-items: start;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 16px;
margin-bottom: 24px;
}

.details-card {
background: #fff;
border: 1px solid #e9e9e9;
border-radius: 8px;
overflow: hidden;
}

.details-card-title {
padding: 14px 16px;
font-size: 16px;
font-weight: 600;
border-bottom: 1px solid #eee;
background: #fafafa;
}

.details-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 16px;
border-bottom: 1px solid #f3f3f3;
}

.details-item:last-child {
border-bottom: none;
}

.details-item span {
color: #666;
}

.details-item strong {
font-weight: 600;
font-size: 15px;
}

/* =========================
Table
========================= */
Expand Down Expand Up @@ -124,6 +172,9 @@ pre {
.json-compare > div {
flex: 1;
min-width: 0;
padding: 10px;
border-bottom: 1px solid #eee;
text-align: left;
}

/* =========================
Expand Down Expand Up @@ -194,3 +245,54 @@ pre {
color: #e74c3c;
font-weight: bold;
}


/* =========================
Accordion
========================= */

.accordion-section {
background: #fff;
border-radius: 8px;
margin-bottom: 14px;
overflow: hidden;
border: 1px solid #e9e9e9;
}

.accordion-header {
/*min-height: 56px;*/
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 10px;
cursor: pointer;
user-select: none;
background: #fafafa;
border-bottom: 1px solid #eee;
}

.accordion-header:hover {
background: #f3f3f3;
}

.accordion-title {
font-size: 16px;
font-weight: 600;
}

.accordion-meta {
font-size: 22px;
color: #777;
font-weight: 300;
width: 24px;
text-align: center;
flex-shrink: 0;
}

.accordion-body {
display: none;
}

.accordion-body.open {
display: block;
}
94 changes: 85 additions & 9 deletions DebugProbe.AspNetCore/Resources/html/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,86 @@

<h2>{{method}} {{path}}</h2>

<p><b>Status:</b> {{status}}</p>
<p><b>TraceId:</b> {{tradeId}}</p>
<p><b>Time:</b> {{time}}</p>
<p><b>Local:</b> {{local}}</p>
<p><b>Env:</b> {{env}}</p>
<p><b>Culture:</b> {{culture}}</p>
<div class="details-grid">

<div class="details-card">
<div class="details-card-title">Overview</div>

<div class="details-item">
<span>Status</span>
<strong>{{status}}</strong>
</div>

<div class="details-item">
<span>TraceId</span>
<strong>{{tradeId}}</strong>
</div>

<div class="details-item">
<span>Time</span>
<strong>{{time}}</strong>
</div>

<div class="details-item">
<span>Local</span>
<strong>{{local}}</strong>
</div>

<div class="details-item">
<span>Duration</span>
<strong>{{durationMs}} ms</strong>
</div>

<div class="details-item">
<span>Request Size</span>
<strong>{{requestSize}} B</strong>
</div>

<div class="details-item">
<span>Response Size</span>
<strong>{{responseSize}} B</strong>
</div>
</div>

<div class="details-card">
<div class="details-card-title">Environment</div>

<div class="details-item">
<span>Environment</span>
<strong>{{env}}</strong>
</div>

<div class="details-item">
<span>Culture</span>
<strong>{{culture}}</strong>
</div>

<div class="details-item">
<span>Machine</span>
<strong>{{machineName}}</strong>
</div>

<div class="details-item">
<span>TimeZone</span>
<strong>{{timeZone}}</strong>
</div>

<div class="details-item">
<span>Decimal</span>
<strong>{{decimalSeparator}}</strong>
</div>

<div class="details-item">
<span>Date Format</span>
<strong>{{dateFormat}}</strong>
</div>

<div class="details-item">
<span>Version</span>
<strong>{{assemblyVersion}}</strong>
</div>
</div>
</div>

<h3>Request URL</h3>
<div class="code-block">
Expand All @@ -31,9 +105,11 @@ <h3>Response Body</h3>

<h3>Compare</h3>

<input id="baseUrl" placeholder="http://server:port" />
<input id="compareId" placeholder="trace id" />
<button onclick="runCompare()">Compare</button>
<div style="padding-bottom:14px;">
<input id="baseUrl" placeholder="http://server:port" />
<input id="compareId" placeholder="trace id" />
<button onclick="runCompare()">Compare</button>
</div>

<div id="compareResult"></div>

Expand Down
Loading