.NET 6 中的 MiniProfiler 动态响应处理
MiniProfiler dynamic response handling in .NET 6
最近我将 MiniProfiler 集成到 .NET 6 API 中并且一切正常,可以通过 EFCore 和仪表板上的所有内容看到 SQL 查询。我现在想要实现的是,分析器仍然像现在一样分析所有 HTTP 请求,但是当应用程序中的任何地方发生错误时(状态代码!= 200)我想用分析器数据做一些自定义的事情,例如,将探查器跟踪(与仪表板上显示的内容相同)保存到数据库或记录器中。
我最初的想法是制作一个自定义中间件,然后在 await _next(context);
之后从 MiniProfiler.Current
的分析器中获取数据(持续时间、步骤、类型、查询),但我似乎无法让它发挥作用。有什么解决办法吗?
在这里找到了一些帮助 。
总而言之,我已经设法编写了一个自定义中间件,它在响应返回到客户端之前从 MiniProfiler 获取所有数据,从而能够捕获堆栈时间,将日志保存到数据库并在以后分析它们。完整的解决方案还包含保存确切的请求和响应数据,这使得能够看到 HTTP 请求的完整范围,但为了简单起见,我将只添加 MiniProfiler 代码:
public async Task InvokeAsync(HttpContext context)
{
// Call the next delegate/middleware in the pipeline.
await _next(context);
try
{
if (context.Response.StatusCode != StatusCodes.Status200OK)
{
var profiler = MiniProfiler.Current;
if (profiler == null)
{
return;
}
profiler.Stop();
var time = timing.DurationMilliseconds != null ? decimal.Round(timing.DurationMilliseconds.Value, 2) : 0;
//Write to Console or Logger
Console.WriteLine($"{new string('>', timing.Depth)} {timing.Name} {time}ms");
if (timing.HasCustomTimings)
{
foreach (var timingType in timing.CustomTimings)
{
foreach (var queryTiming in timingType.Value)
{
var message = $"{new string('>', timing.Depth + 1)} ({timingType.Key},{queryTiming.DurationMilliseconds}ms) {queryTiming.CommandString.Replace("\r\n", " ")}";
//Write to Console or Logger
Console.WriteLine(message);
}
}
}
}
}
catch (Exception)
{
//Do something
}
}
最近我将 MiniProfiler 集成到 .NET 6 API 中并且一切正常,可以通过 EFCore 和仪表板上的所有内容看到 SQL 查询。我现在想要实现的是,分析器仍然像现在一样分析所有 HTTP 请求,但是当应用程序中的任何地方发生错误时(状态代码!= 200)我想用分析器数据做一些自定义的事情,例如,将探查器跟踪(与仪表板上显示的内容相同)保存到数据库或记录器中。
我最初的想法是制作一个自定义中间件,然后在 await _next(context);
之后从 MiniProfiler.Current
的分析器中获取数据(持续时间、步骤、类型、查询),但我似乎无法让它发挥作用。有什么解决办法吗?
在这里找到了一些帮助
public async Task InvokeAsync(HttpContext context)
{
// Call the next delegate/middleware in the pipeline.
await _next(context);
try
{
if (context.Response.StatusCode != StatusCodes.Status200OK)
{
var profiler = MiniProfiler.Current;
if (profiler == null)
{
return;
}
profiler.Stop();
var time = timing.DurationMilliseconds != null ? decimal.Round(timing.DurationMilliseconds.Value, 2) : 0;
//Write to Console or Logger
Console.WriteLine($"{new string('>', timing.Depth)} {timing.Name} {time}ms");
if (timing.HasCustomTimings)
{
foreach (var timingType in timing.CustomTimings)
{
foreach (var queryTiming in timingType.Value)
{
var message = $"{new string('>', timing.Depth + 1)} ({timingType.Key},{queryTiming.DurationMilliseconds}ms) {queryTiming.CommandString.Replace("\r\n", " ")}";
//Write to Console or Logger
Console.WriteLine(message);
}
}
}
}
}
catch (Exception)
{
//Do something
}
}