.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
    }
}