<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mahmood Al Sarraj</title>
    <description>The latest articles on DEV Community by Mahmood Al Sarraj (@mahmood-alsarraj).</description>
    <link>https://dev.to/mahmood-alsarraj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3946589%2F3bb3060e-112c-486a-9c8f-169c67dc4b9d.png</url>
      <title>DEV Community: Mahmood Al Sarraj</title>
      <link>https://dev.to/mahmood-alsarraj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mahmood-alsarraj"/>
    <language>en</language>
    <item>
      <title>Add a Live Observability Dashboard to Your ASP.NET Core App in 5 Minutes — No External Services Needed</title>
      <dc:creator>Mahmood Al Sarraj</dc:creator>
      <pubDate>Mon, 29 Jun 2026 14:56:34 +0000</pubDate>
      <link>https://dev.to/mahmood-alsarraj/add-a-live-observability-dashboard-to-your-aspnet-core-app-in-5-minutes-no-external-services-4k6p</link>
      <guid>https://dev.to/mahmood-alsarraj/add-a-live-observability-dashboard-to-your-aspnet-core-app-in-5-minutes-no-external-services-4k6p</guid>
      <description>&lt;h2&gt;
  
  
  No Grafana. No Datadog. No YAML. Just visibility.
&lt;/h2&gt;

&lt;p&gt;You've shipped your ASP.NET Core API. It's live. And then your product manager pings you: "Something seems slow - can you check?"&lt;/p&gt;

&lt;p&gt;You open the logs. Wall of text. No correlation IDs. No timing. No idea which request threw that exception at 2 AM.&lt;br&gt;
Sound familiar?&lt;/p&gt;

&lt;p&gt;That's the problem AsGuard solves.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is&amp;nbsp;AsGuard?
&lt;/h2&gt;

&lt;p&gt;AsGuard is a lightweight NuGet package that plugs directly into your ASP.NET Core middleware pipeline and gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full HTTP request/response logging&lt;/strong&gt; with timing, method, status, and body capture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exception tracking&lt;/strong&gt; with stack traces, severity, and trends - no Sentry account required&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host ILogger capture&lt;/strong&gt; - your existing LogWarning and LogError calls get stored and searchable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A built-in live dashboard&lt;/strong&gt; with dark/light mode, SSE-powered real-time updates, and filtering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire thing runs inside your app. No external services. No Docker compose file with six containers. No licensing tiers. Just a NuGet package and four lines of configuration.&lt;/p&gt;


&lt;h2&gt;
  
  
  Getting It Running (For Real, Under 5&amp;nbsp;Minutes)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1 - Install the&amp;nbsp;package&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;AsGuard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 - Configure in Program.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;AsGuard.Extensions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;AsGuard.Domain.RequestLogging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRequestLogging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoggingDatabaseProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sqlite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Data Source=asguard.db"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DashboardRoute&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/logs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DashboardUsername&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"AsGuard:Username"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DashboardPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"AsGuard:Password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"change-me"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnableExceptionLogging&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CaptureHostLogs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogResponseBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogRequestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3 - Register the middleware&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The placement matters. Add &lt;code&gt;UseRequestLogging()&lt;/code&gt; after HTTPS/CORS but before auth and your endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRequestLogging&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// ← right here&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4 - Hit the dashboard&lt;/strong&gt;&lt;br&gt;
Run your app, open a browser, and navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://localhost:&amp;lt;port&amp;gt;/logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxygozh19krtfka66vg5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxygozh19krtfka66vg5x.png" alt="AsGuard main dashboard" width="799" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter your credentials and you'll see a live dashboard with every request your app has handled. That's it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Middleware Order Actually&amp;nbsp;Matters
&lt;/h2&gt;

&lt;p&gt;One gotcha worth knowing upfront: where you place &lt;code&gt;UseRequestLogging()&lt;/code&gt; in the pipeline determines what gets captured.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HTTP Request In]
       │
       ▼
┌──────────────────────┐
│ Exception Handler    │  ← register first so AsGuard can intercept exceptions
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ HTTPS / CORS / HSTS  │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│  UseRequestLogging() │  ← HERE: correlation IDs generated, body stream opened
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│  Auth &amp;amp; Authorization│  ← 401s and 403s will still be logged
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│  Your Endpoints      │
└──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Placing it after auth means you lose logs for unauthorized requests. Placing it before exception handlers means unhandled exceptions won't have their HTTP context correctly linked. The order shown above gets you everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing a&amp;nbsp;Database
&lt;/h2&gt;

&lt;p&gt;AsGuard supports four providers out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQLite -&lt;/strong&gt; zero setup, file-based; perfect for local dev, small apps, and quick demos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQL Server -&lt;/strong&gt; the natural fit for production on Azure or Windows-hosted workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL -&lt;/strong&gt; ideal for Linux environments and cloud-native stacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In-Memory -&lt;/strong&gt; no persistence, no config; great for integration tests and ephemeral environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switching is one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PostgreSQL&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoggingDatabaseProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostgreSql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Host=localhost;Database=asguard;Username=postgres;Password=pass"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// In-Memory (no persistence, great for tests)&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoggingDatabaseProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InMemory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxInMemoryEntries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No migrations to run manually. AsGuard auto-creates its tables on startup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Masking Sensitive Data
&lt;/h2&gt;

&lt;p&gt;If you capture request bodies (and you should, for debugging), you don't want passwords showing up in your log viewer. AsGuard gives you two ways to handle this.&lt;br&gt;
&lt;strong&gt;Per-property attribute:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginRequest&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Username&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AsGuardMasked&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// stored as "[REDACTED]"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Global key list in config:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SensitiveBodyKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"creditCardNumber"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SensitiveBodyKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ssn"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SensitiveBodyKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs at the middleware level before anything hits the database - you're never storing what you shouldn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You'll Actually Use It&amp;nbsp;For
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Debugging slow requests in development
&lt;/h3&gt;

&lt;p&gt;The request log view shows method, path, status code, and duration for every call. You can filter by status, search by path, and click into any row to see the full request/response bodies, headers, and the correlation ID chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tracking down production exceptions
&lt;/h3&gt;

&lt;p&gt;Exception logging captures the full stack trace, the HTTP context it occurred in, the severity, and when it happened. The dashboard includes trend charts so you can see if your error rate just spiked after a deploy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Capturing ILogger&amp;nbsp;output
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;CaptureHostLogs = true&lt;/code&gt;, any &lt;code&gt;LogWarning&lt;/code&gt; or &lt;code&gt;LogError&lt;/code&gt; your existing services emit gets stored alongside the HTTP logs. You don't need to change a single line of your existing logging code - AsGuard just intercepts the host &lt;code&gt;ILogger&lt;/code&gt; pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  APM for EF Core and HttpClient
&lt;/h3&gt;

&lt;p&gt;AsGuard auto-instruments EF Core queries and outbound &lt;code&gt;HttpClient&lt;/code&gt; calls, showing them as Gantt-style trace timelines per request. If one endpoint is slow because it's firing 12 database queries, you'll see exactly which ones and how long each took.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvwg1wzpz5tvgivj1lxey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvwg1wzpz5tvgivj1lxey.png" alt="AsGuard AMP, Http Calls, EF queries" width="728" height="835"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Seeing what's live, right&amp;nbsp;now
&lt;/h3&gt;

&lt;p&gt;The dashboard uses Server-Sent Events for real-time updates - no page refresh, no polling interval to configure. While you're load testing or manually poking an endpoint, the request log updates in front of you.&lt;/p&gt;




&lt;h3&gt;
  
  
  Production Notes
&lt;/h3&gt;

&lt;p&gt;A few things to know before deploying:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change the default credentials.&lt;/strong&gt; AsGuard actively rejects the literal string "admin" as a username. Store credentials in environment variables or user secrets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# environment variable approach&lt;/span&gt;
&lt;span class="s"&gt;ASGUARD__USERNAME=your_secure_user&lt;/span&gt;
&lt;span class="s"&gt;ASGUARD__PASSWORD=your_secure_password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The write path is non-blocking.&lt;/strong&gt; AsGuard uses a queue-based architecture - logs are written to an in-process channel and flushed asynchronously. Your API response times are not affected by database write latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set up retention policies.&lt;/strong&gt; For high-traffic apps, configure auto-cleanup so the log table doesn't grow unbounded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetentionDays&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SQLite&lt;/strong&gt; is fine for low-to-medium traffic. For anything handling hundreds of requests per second in production, switch to PostgreSQL or SQL Server.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Bigger&amp;nbsp;Picture
&lt;/h3&gt;

&lt;p&gt;Most&amp;nbsp;.NET teams reach for Sentry for exceptions, Datadog or Azure Monitor for metrics, and a custom Kibana setup for logs. That's three services, three SDKs, three dashboards, and three monthly bills.&lt;/p&gt;

&lt;p&gt;AsGuard doesn't replace that stack for large-scale production systems. But for the majority of apps - internal tools, SaaS products under 100k requests/day, staging environments, side projects - it gives you 80% of the observability value at 0% of the infrastructure overhead.&lt;/p&gt;

&lt;p&gt;Install it in your existing app today and you'll have a searchable, live view of every request and exception by the time your coffee's ready.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/mahmood-alsarraj/asguard" rel="noopener noreferrer"&gt;mahmood-alsarraj/asguard&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NuGet:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/AsGuard/" rel="noopener noreferrer"&gt;nuget/AsGuard&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If this saved you a debugging session, give the repo a star ⭐ - it helps.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>datadog</category>
      <category>observability</category>
      <category>grafana</category>
    </item>
  </channel>
</rss>
