Skip to content

About

A lightweight, developer-friendly debugging dashboard for ASP.NET Core apps inspired by Laravel Telescope

Resources

Contributing

Security policy

Stars

31 stars

Watchers

0 watching

Forks

Repository files navigation

ASP.NET Debug Dashboard

ASP.NET Debug Dashboard

CI NuGet Downloads License: MIT Ko-fi

Request, SQL query, log, and exception capture for ASP.NET Core, viewable in a dashboard at /_debug, and the hub of a small suite of local-first dev tools. Think Laravel Telescope, but for .NET.

Everything is stored locally in a LiteDB file. The dashboard ships inside the package as a single self-contained page, so there are no CDN dependencies and it works offline.

Demo

The suite

The dashboard is the hub of a set of local-first dev tools that follow the same recipe: install a package, get a self-contained page at a /_* route, no extra infrastructure. Each works on its own, and when more than one is installed they share a sidebar so you can move between them.

Suite

Package NuGet Route What it does
AspNetDebugDashboard NuGet /_debug Request, SQL, log, and exception capture (this package).
AspNetMailbox NuGet /_mailbox Captures outbound email in-process and previews it (HTML, text, headers, attachments). No mail server.
AspNetFlags NuGet /_flags Feature flags with a toggle UI. Flags appear the first time your code checks them.
AspNetJobs NuGet /_jobs Background jobs that run in-process, with a live inspector showing status, timing, and stack traces.
AspNetVitals NuGet /_vitals Live memory, GC, threads, uptime, and your registered health checks on one page.

There's also AspNetDebugDashboard.Mcp to expose all of it to an AI agent over MCP. Install only what you want; nothing else is pulled in.

Install

dotnet add package AspNetDebugDashboard

Or in the project file:

<PackageReference Include="AspNetDebugDashboard" Version="2.2.0" />

Or from the Package Manager Console in Visual Studio:

Install-Package AspNetDebugDashboard

Works on .NET 8, 9, and 10. No other setup files, schemas, or services needed. Storage is an embedded LiteDB database created on first run.

Setup

The minimum is two lines:

using AspNetDebugDashboard.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDebugDashboard();          // 1. register services

var app = builder.Build();

app.UseDebugDashboard();                       // 2. add middleware (no-op outside Development)

app.MapControllers();
app.Run();

Run your app and open /_debug.

Capture EF Core queries

Attach the interceptor when registering your context:

builder.Services.AddDbContext<AppDbContext>((sp, options) =>
{
    options.UseSqlServer(connectionString);    // any relational provider
    options.AddDebugDashboard(sp);
});

Works with SQL Server, PostgreSQL, SQLite, MySQL, anything that goes through EF Core's relational pipeline. (UseInMemoryDatabase produces no SQL, so there's nothing to capture there.)

Write your own log entries

Inject IDebugLogger anywhere:

public class OrderService(IDebugLogger log)
{
    public async Task<Order> CreateAsync(CreateOrderRequest req)
    {
        await log.LogInfoAsync("Creating order", properties: new() { ["customerId"] = req.CustomerId });
        // LogWarningAsync, LogErrorAsync, LogSuccessAsync, or LogAsync(message, level)
    }
}

Or use the static logger where injection is awkward:

await DebugLogger.InfoAsync("Cache warmed", tag: "startup");

Entries written during a request are attached to it, so the request detail shows the logs and queries it produced.

The dashboard

Overview totals, error rate, status/method distribution, slowest requests and queries
Performance req/min, avg, median, P95/P99, error rate, slowest endpoints (last hour)
Requests sortable table with duration bars; detail has Summary / Headers / Request / Response / SQL / Logs tabs and a copy-as-cURL button
Queries full SQL with syntax highlighting, parameters, timing; slow queries flagged; an N+1 warning appears when one request runs the same query 3+ times
Logs level, category, structured properties, stack traces
Exceptions type, message, full stack trace, inner exceptions, the route that threw

Global search (Ctrl+K) covers everything. Tables navigate from the keyboard: j/k rows, Enter open, / filter, Esc close. Queries, logs, and exceptions link back to their parent request.

Overview

Request detail

Query detail

Configuration

All options, with their defaults:

builder.Services.AddDebugDashboard(options =>
{
    options.BasePath = "/_debug";              // dashboard route
    options.DatabasePath = "debug-dashboard.db";
    options.MaxEntries = 1000;                 // per entry type, oldest trimmed first
    options.LogRequestBodies = true;
    options.LogResponseBodies = false;
    options.MaxBodySize = 1024 * 1024;         // bodies above this are skipped
    options.SlowQueryThresholdMs = 1000;
    options.ExcludedPaths = new() { "/_debug", "/health" };
    options.ExcludedHeaders = new() { "Authorization", "Cookie", "Set-Cookie", "X-Api-Key", "X-Auth-Token", "Proxy-Authorization" };
    options.RedactedBodyFields = new() { "password", "secret", "token", "apikey" }; // matched case-insensitively against JSON and form field names
    options.AllowedEnvironments = new() { "Development" }; // "*" allows every environment
    options.AuthorizationFilter = null;        // Func<HttpContext, bool>, applied to UI + API
    options.RetentionPeriod = TimeSpan.FromDays(7);
});

Or bind from appsettings.json:

{
  "DebugDashboard": {
    "MaxEntries": 2000,
    "LogResponseBodies": true,
    "SlowQueryThresholdMs": 500
  }
}
builder.Services.Configure<DebugConfiguration>(builder.Configuration.GetSection("DebugDashboard"));
builder.Services.AddDebugDashboard();

The full reference is in docs/CONFIGURATION.md.

OpenTelemetry

Captured requests and queries are also emitted as spans on an ActivitySource named AspNetDebugDashboard. Add that source to your tracer and they flow to Aspire, Jaeger, or any OTLP backend, alongside what the dashboard stores locally:

builder.Services.AddOpenTelemetry()
    .WithTracing(t => t
        .AddSource("AspNetDebugDashboard")
        .AddOtlpExporter());

The spans carry the request id, status, SQL text, and timing. They cost nothing until you add the source (no listener, no span), so the default is fine to leave on. Set EmitActivities = false to turn it off entirely. Details in docs/OPENTELEMETRY.md.

MCP server for AI agents

NuGet Downloads

AspNetDebugDashboard.Mcp is a separate dotnet tool that exposes the captured data to a coding agent over MCP, so it can read recent requests, the SQL a request ran, recent failures, and performance numbers while it works on your app. If you've installed the rest of the suite, it can also read your feature flags, background jobs, vitals, and captured mail.

dotnet tool install --global AspNetDebugDashboard.Mcp
{
  "mcpServers": {
    "debug-dashboard": {
      "command": "aspnet-debug-mcp",
      "env": { "DEBUG_DASHBOARD_URL": "http://localhost:5000" }
    }
  }
}

Setup and the full tool list are in its README.

Production

The dashboard's UI, API, and EF interceptor all check IsEnabled and the current environment against AllowedEnvironments (default: Development only) before doing anything, and they check it themselves rather than relying on UseDebugDashboard() being called a particular way. That holds even if MapControllers() is registered unconditionally, so requests outside an allowed environment get a 404 regardless of how the pipeline is wired.

If you want it on elsewhere (a staging box, say), opt in explicitly:

app.UseDebugDashboard(forceEnable: true);

This enables the dashboard and adds the current environment to AllowedEnvironments. You can also set AllowedEnvironments directly in AddDebugDashboard, or use "*" to allow every environment.

If you enable it anywhere reachable from the internet, set AuthorizationFilter too:

services.AddDebugDashboard(options =>
{
    options.AuthorizationFilter = ctx => ctx.User.IsInRole("Admin");
});

It runs on every dashboard UI and API request and returns 401 when it returns false. Without it, the dashboard has no auth of its own, and captured request bodies can contain anything your users send (though known password/secret/token/apikey fields are redacted by default; see RedactedBodyFields).

REST API

The dashboard is a client of a plain JSON API you can also call directly:

Endpoint What it returns
GET /_debug/api/stats totals and distributions
GET /_debug/api/requests paged requests; supports search, method, statusCode, isSuccessful, minExecutionTime, sortBy, page
GET /_debug/api/queries paged SQL queries; supports search, isSlowQuery, isSuccessful
GET /_debug/api/logs paged logs; supports search, level
GET /_debug/api/exceptions paged exceptions
GET /_debug/api/performance last-hour metrics (P95/P99, error rate, slowest endpoints)
GET /_debug/api/search?term= cross-type search
GET /_debug/api/export everything as a JSON file
POST /_debug/api/logs write a log entry over HTTP
DELETE /_debug/api/clear wipe all captured data

Full details in docs/API.md.

Try it

The repo ships a sample app with endpoints for generating traffic, slow operations, and test exceptions:

git clone https://github.com/eladser/AspNetDebugDashboard
cd AspNetDebugDashboard
dotnet run --project samples/SampleApp --urls http://localhost:5000
# hit a few endpoints, then open http://localhost:5000/_debug
curl http://localhost:5000/api/products
curl http://localhost:5000/api/products/slow-operation
curl http://localhost:5000/api/products/test-error

How the dashboard is built

The UI is a Vite + React app in dashboard/, compiled to one HTML file with everything inlined and embedded into the assembly. To work on it:

cd dashboard
npm install
npm run dev    # proxies /_debug/api to localhost:5000 (run the sample app alongside)
npm run build  # writes src/AspNetDebugDashboard/wwwroot/index.html

See CONTRIBUTING.md for the full dev loop.

Support

If this tool saves you some debugging time, you can buy me a coffee.

License

MIT. See LICENSE.

About

A lightweight, developer-friendly debugging dashboard for ASP.NET Core apps inspired by Laravel Telescope

Resources

Contributing

Security policy

Stars

31 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages