2

Is it possible to get the same level of information from mini-profiler when using it in a console app as you can get when in a web app? Ideally, I'd just like to self host the web UI in the console, but it doesn't look like that's possible.

My main goal is to get the sqlqueries that are being executed out as/when calls are made and their parameters/run time. I've tried the RenderPlainText() solution, and its nowhere near as detailed as the webview, and there doesn't seem to be a hook I can use to log its contents when something interesting happens.

MrEdmundo
  • 5,105
  • 13
  • 46
  • 58
gmn
  • 4,199
  • 4
  • 24
  • 46

1 Answers1

4

There isn't a built-in way to get a full-fledged text-based output of profiler (RenderPlainText() is what's in the box) since people all seem to want various pieces of complex data. But there are a few options! You can:

  • Render the profiler output manually, by crawling the timings. If you just want the query list, you could loop over all query-level timings and print out their custom timings. That sounds ominous since it's a tree, but there is profiler.GetTimingHierarchy() available for this to get them all as a list, for example:
var profiler = MiniProfiler.StartNew();
using (profiler.Step("MyStep"))
using (profiler.CustomTiming("sql", "Select *"))
{
    // Stuff
}
profiler.Stop();

foreach (var timing in profiler.GetTimingHierarchy())
{
    if (timing.HasCustomTimings)
    {
        foreach (var timingType in timing.CustomTimings)
        {
            Console.WriteLine(timingType.Key + " queries:");
            foreach (var queryTiming in timingType.Value)
            {
                Console.WriteLine($"  {queryTiming.DurationMilliseconds} ms - {queryTiming.CommandString}");
            }
        }
    }
}

Which would yield:

sql queries:
  0.9 ms - Select *
  • Or, more complicated, use a shared storage for the profilers and view them in a web app anywhere. For example if you setup the console app to store in Redis (the default is in-memory), then you could point a web app at the same storage and use the web UI to view them. You just need to make sure your "user" ID matches. That's the .UserIdProvider on options (defaults to IP address on the web side). For example, in ASP.NET Core:
services.AddMiniProfiler(options =>
{
   options.UserIdProvider = request => MyGetUserIdFunction(request);
});

When going with the second option, note that the URLs are consistent and all that's changing is the GUID if you click "share" from a MiniProfiler web UI. You could take the current profiler.Id and use that to spit out a handy link to your console.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155