Recorder 0.9.1
dotnet add package Recorder --version 0.9.1
NuGet\Install-Package Recorder -Version 0.9.1
<PackageReference Include="Recorder" Version="0.9.1" />
paket add Recorder --version 0.9.1
#r "nuget: Recorder, 0.9.1"
// Install Recorder as a Cake Addin #addin nuget:?package=Recorder&version=0.9.1 // Install Recorder as a Cake Tool #tool nuget:?package=Recorder&version=0.9.1
Recorder
Record high level profiling data in ASP.NET Core applications at runtime. Profiles can then be visualized using speedscope.
Usage
To use the recorder, register the middleware then request a BlackBox
recorder at runtime to instrument different subsystems. The blackbox will store a configurable number of request profiles (default is 16).
Register types
// use default profile naming (root stack frame will have a name like 'GET relative/url?queryparams')
builder.Services.AddRequestRecording();
// for custom naming, implement INomenclator
builder.Services.AddRequestRecording<MyNomenclator>();
Register middleware
At startup, register the middleware:
// always run
app.UseRequestRecorder();
// profile specific URL
app.UseWhen(context => context.Request.Path.StartsWithSegments("Foo") , appBuilder =>
{
appBuilder.UseRequestRecorder();
});
Instrument code
For example, to instrument output create an instrumented formatter and decorate the existing formatter classes.
public class InstrumentedOutputFormatter : IOutputFormatter
{
private readonly IOutputFormatter inner;
public InstrumentedOutputFormatter(IOutputFormatter inner) { this.inner = inner; }
public bool CanWriteResult(OutputFormatterCanWriteContext context)
{
return inner.CanWriteResult(context);
}
public async Task WriteAsync(OutputFormatterWriteContext context)
{
// record time spent in this method via Capture
using var frame = context.HttpContext.RequestServices.RecordStackFrame("OutputFormatter");
await inner.WriteAsync(context);
}
}
builder.Services
.AddMvcOptions(options =>
{
// wrap all the formatters with instrumentation
List<IOutputFormatter> newFormatters = new List<IOutputFormatter>(options.OutputFormatters.Count);
foreach (var f in options.OutputFormatters)
{
newFormatters.Add(new InstrumentedOutputFormatter(f));
}
options.OutputFormatters.Clear();
foreach (var nf in newFormatters)
{
options.OutputFormatters.Add(nf);
}
});
Add a profiling controller
Add a controller to integrate with speedscope easily at runtime by sending HTTP GET to https://localhost/profile. This controller will first redirect the caller to speedscope with a parameterized profile URL. When speedscope requests the profile data, detect it via the origin header and return the profile.
builder.Services.AddCors(options =>
{
options.AddPolicy(ProfileDataController.CorsPolicyName,
builder =>
{
builder
.WithOrigins(@"https://www.speedscope.app")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
// ...
app.UseCors(ProfileDataController.CorsPolicyName);
[ApiController]
[Route("[controller]")]
public class ProfileController : ControllerBase
{
public const string CorsPolicyName = "allowSpeedscope";
[EnableCors(CorsPolicyName)]
public async Task<IActionResult> Get()
{
if (this.HttpContext.Request.Headers.TryGetValue("Origin", out var origin) && origin[0] == "https://www.speedscope.app")
{
var memoryStream = new MemoryStream();
using (var speedscopeWriter = new SpeedscopeWriter(memoryStream))
{
speedscopeWriter.WritePreAmble();
foreach (var request in BlackBox.History)
{
speedscopeWriter.WriteEvent(request);
}
speedscopeWriter.Flush();
}
memoryStream.Position = 0;
var fileResult = File(memoryStream, "application/json", "profile.json");
return fileResult;
}
if (!BlackBox.HasHistory)
{
return NotFound("No profiles have been recorded");
}
return Redirect($"https://speedscope.app#profileURL=https://{this.HttpContext.Request.Host}/Profile");
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.AspNetCore.Mvc.Core (>= 2.2.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.