๐ ASP.NET Core Logging: Your Appโs Secret Diary
The Story of the Talking Robot ๐ค
Imagine you have a toy robot that canโt speak. When something goes wrong, you have no idea what happened! Now imagine if that robot could write everything down in a secret diaryโevery button you pressed, every time it got confused, every happy moment when it worked perfectly.
Thatโs exactly what logging is in ASP.NET Core! Your application writes down everything it does, so when something breaks, you can read the diary and figure out what went wrong.
๐ฏ What is Logging in ASP.NET Core?
Think of logging like leaving a trail of breadcrumbs in a forest. If you get lost, you can follow the breadcrumbs back!
Logging = Your app talking to you (even when youโre not watching)
// Your app says "Hello!"
logger.LogInformation("App started!");
// Your app warns you
logger.LogWarning("Disk is getting full!");
// Your app screams for help
logger.LogError("Database crashed!");
Built-In Magic โจ
ASP.NET Core comes with logging already installed. You donโt need to add anything special to start!
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(
ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Someone visited home!");
return View();
}
}
What happens? Every time someone visits your home page, your app writes โSomeone visited home!โ in its diary.
โ๏ธ Logging Configuration
Where Does the Diary Live?
You tell your app WHERE to write its diary and WHAT to write using appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"System": "Warning"
}
}
}
The Configuration Breakdown
| Setting | What It Means |
|---|---|
Default |
How chatty is everyone? |
Microsoft |
How chatty is the framework? |
System |
How chatty are system parts? |
Multiple Diaries! ๐
Your app can write to multiple places at once:
builder.Logging.ClearProviders();
builder.Logging.AddConsole(); // Screen
builder.Logging.AddDebug(); // Debug window
builder.Logging.AddEventLog(); // Windows Event Log
Think of it like: Writing the same story in your notebook AND texting it to mom AND posting it on the fridge!
๐ Log Levels: The Volume Knob
Imagine your robot has a volume knob from 0 to 6. The higher the number, the more serious the message!
graph TD A["๐ Trace - 0"] --> B["๐ Debug - 1"] B --> C["๐ Information - 2"] C --> D["๐ Warning - 3"] D --> E["๐ข Error - 4"] E --> F["๐จ Critical - 5"] F --> G["๐ None - 6"] style A fill:#e8e8e8 style B fill:#87ceeb style C fill:#90EE90 style D fill:#FFD700 style E fill:#FFA500 style F fill:#FF6B6B style G fill:#808080
What Each Level Means
| Level | When to Use | Example |
|---|---|---|
| Trace | Super detailed detective work | "Checking if user exists..." |
| Debug | Developer troubleshooting | "User ID is 42" |
| Information | Normal happy events | "Order placed!" |
| Warning | Something odd happened | "Retry attempt 2 of 3" |
| Error | Something broke! | "Payment failed!" |
| Critical | App is on fire! ๐ฅ | "Database connection lost!" |
Code Examples for Each Level
_logger.LogTrace("Starting method X");
_logger.LogDebug("User ID: {UserId}", userId);
_logger.LogInformation("Order {OrderId} placed", orderId);
_logger.LogWarning("Cache miss for key {Key}", key);
_logger.LogError(ex, "Payment failed for {UserId}", userId);
_logger.LogCritical("DATABASE DOWN! PANIC!");
The Filter Rule ๐๏ธ
If you set level to Warning, youโll see:
- โ Warning
- โ Error
- โ Critical
- โ Information (hidden)
- โ Debug (hidden)
- โ Trace (hidden)
Higher levels = More serious = Always shown
๐๏ธ Structured Logging: Smart Diaries
Old Way (Dumb Strings) ๐
// BAD - Just a boring string
_logger.LogInformation(
"User 42 bought product ABC for $99");
New Way (Smart Data) ๐ง
// GOOD - Structured with named values!
_logger.LogInformation(
"User {UserId} bought {Product} for {Price}",
42, "ABC", 99.00);
Why Structured is Better?
graph TD A["Structured Log"] --> B["Search by UserId"] A --> C["Filter by Product"] A --> D["Sum all Prices"] A --> E["Create Charts"] style A fill:#667eea,color:white style B fill:#90EE90 style C fill:#90EE90 style D fill:#90EE90 style E fill:#90EE90
Old way: Like writing โJohn bought applesโ on paper New way: Like filling a form with Name: John, Item: Apples
Now you can easily:
- Find all logs for User 42
- Count how many times โABCโ was bought
- Calculate total money spent
Scopes: Adding Context
using (_logger.BeginScope(
"Processing Order {OrderId}", orderId))
{
_logger.LogInformation("Checking inventory");
_logger.LogInformation("Processing payment");
_logger.LogInformation("Sending email");
}
// All 3 logs include OrderId automatically!
๐ Serilog Integration: The Super Diary
Serilog is like upgrading from a paper diary to a super-powered digital journal that can:
- Write to 100+ different places
- Search through millions of entries instantly
- Create beautiful charts and dashboards
Step 1: Install the Packages
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
Step 2: Configure in Program.cs
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("logs/app-.log",
rollingInterval: RollingInterval.Day)
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
Step 3: Use It!
public class OrderController : Controller
{
private readonly ILogger<OrderController> _logger;
public IActionResult Create(Order order)
{
_logger.LogInformation(
"New order {@Order}", order);
// {@Order} = logs the WHOLE object!
return Ok();
}
}
Serilog Sinks (Where to Write)
graph TD A["Your App"] --> B["Serilog"] B --> C["๐บ Console"] B --> D["๐ File"] B --> E["๐ Seq"] B --> F["โ๏ธ Azure"] B --> G["๐ง Email"] B --> H["๐ฌ Slack"] style A fill:#667eea,color:white style B fill:#FFD700
Enrichers: Auto-Add Info
Log.Logger = new LoggerConfiguration()
.Enrich.WithMachineName()
.Enrich.WithThreadId()
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateLogger();
// Now every log automatically includes:
// - Computer name
// - Thread ID
// - Any context you add
Configuration via appsettings.json
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "logs/app.log"
}
}
]
}
}
๐ช Putting It All Together
// Program.cs - Complete Setup
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft",
Serilog.Events.LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logs/app-.log",
rollingInterval: RollingInterval.Day)
.CreateLogger();
try
{
Log.Information("Starting application");
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
var app = builder.Build();
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application crashed!");
}
finally
{
Log.CloseAndFlush();
}
๐ฏ Quick Summary
| Concept | Think of it asโฆ |
|---|---|
| Logging | Your appโs secret diary |
| Log Levels | Volume knob (0-6) |
| Configuration | Telling the diary what to write |
| Structured Logging | Smart forms instead of plain text |
| Serilog | Super-powered diary upgrade |
| Sinks | Different places to write the diary |
| Enrichers | Auto-adding extra info |
๐ก Remember This!
โIf your app canโt tell you what happened, youโll never know what went wrong!โ
Logging is like giving your app a voice. The more it talks (appropriately!), the easier your life becomes when things break at 2 AM! ๐
Start simple, grow as needed:
- Use built-in logging first
- Add Serilog when you need superpowers
- Always use structured logging
- Set appropriate log levels
Happy Logging! ๐
