What a request explains
ApiLens is developer-first runtime diagnostics for ASP.NET Core. It answers why one request was slow or failed. Collection stays on System.Diagnostics: the ApiLens middleware, EF Core command events, and System.Net.Http activities.
ASP.NET Core already exposes request, routing, and exception metrics. OpenTelemetry already collects traces and metrics. ApiLens sits above both and explains a single request. It does not ship a second telemetry pipeline.
- A timeline of endpoint time, EF Core commands, and outbound
HttpClientcalls. - Explain percentages as a share of wall-clock time.
- A repeated SQL shape reported as a possible N+1.
- A development dashboard at
/_apilens.
The NuGet id is NuvyntraLabs.NET.ApiLens. endjin/ApiLens is a different project: an XML documentation search tool.
Install
dotnet add package NuvyntraLabs.NET.ApiLens.AspNetCore
dotnet add package NuvyntraLabs.NET.ApiLens.EntityFrameworkCore
dotnet add package NuvyntraLabs.NET.ApiLens.HttpThe app references the ASP.NET Core, Entity Framework Core, and HTTP packages. NuvyntraLabs.NET.ApiLens.UI is pulled in by the ASP.NET Core package. Core has no ASP.NET reference, so the timeline can be tested without a host.
What each assembly owns: Package roles
Register
builder.Services.AddApiLens();
builder.Services.AddApiLensEntityFrameworkCore();
builder.Services.AddApiLensHttp();
app.UseApiLens();AddApiLens() lives on the ASP.NET Core package. EF Core and HTTP reference core only and write into the active request. Call UseApiLens() before endpoints so the middleware wraps the request.
| Option | Default |
|---|---|
| SlowRequestThreshold | 500 ms |
| NPlusOneRepeatThreshold | 8 |
| MaxStoredRequests | 200 |
| EnableDashboard | true (Development only) |
| Capture | null — follows the host environment |
Leave Capture null unless the host environment is the wrong signal. A null value keeps redacted SQL text in Development and timings only everywhere else.
What is stored: Capture and privacy
Sample
dotnet run --project samples/ApiLens.SampleThe sample is an in-memory SQLite web app. GET / redirects to /_apilens. GET /api/orders loads every order, then queries each row again so the dashboard can show a repeated SQL shape.
Open it only in Development: Dashboard