Logging is one of those things every developer knows is important—but often gets ignored until production breaks at 2 AM. Traditional logging (plain text, string concatenation, scattered
Console.WriteLine) makes debugging harder than it needs to be.
That’s where Serilog shines.
Serilog is a structured logging library for .NET that helps you write meaningful, searchable, and production-ready logs with minimal effort.
What Is Serilog?
Serilog is an open-source logging framework for .NET that focuses on structured logging instead of plain text logging.
Instead of logging strings like:
logger.LogInformation("User 25 logged in from 192.168.1.1");
Serilog logs data:
Log.Information("User {UserId} logged in from {IpAddress}", userId, ip);
This makes logs:
- Easier to query
- Easier to analyze
- Perfect for log aggregation tools
Why Structured Logging Matters
Traditional logs are human-readable but machine-unfriendly. Structured logs are both. With Serilog, logs are stored as key–value pairs, not just strings.
Example output (JSON style):
{
"Timestamp": "2026-02-03T10:15:30Z",
"Level": "Information",
"MessageTemplate": "User {UserId} logged in",
"Properties": {
"UserId": 25,
"IpAddress": "192.168.1.1"
}
}
This allows:
- Filtering by
UserId - Searching by
IpAddress - Aggregating errors by type
Perfect for production systems.
Key Features of Serilog
1. Structured Logging by Default
No extra setup. Structured logging is the core design.
2. Multiple Log Destinations (Sinks)
Serilog can write logs to:
- Console
- File
- Rolling files
- SQL Server
- Elasticsearch
- Seq
- Application Insights
- AWS / Azure services
You can log to multiple sinks at once.
3. High Performance
- Asynchronous logging
- Buffered writes
- Minimal overhead
Safe for high-traffic applications.
4. Rich Context Support
Add context like:
- Request ID
- User ID
- Correlation ID
Environment (Dev / QA / Prod)
Installing Serilog in a .NET Project
Step 1: Install Packages
dotnet add package Serilog
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.File
dotnet add package Serilog.Sinks.Console
Basic Serilog Configuration
Program.cs (ASP.NET Core)
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("Logs/app-.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
try
{
Log.Information("Application starting");
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application failed to start");
}
finally
{
Log.CloseAndFlush();
}
This gives you:
- Console logs for development
- Daily rolling log files for production
Using Serilog in Code
Instead of ILogger.LogInformation, you can use:
Log.Information("Order {OrderId} placed by user {UserId}", orderId, userId);
Or with dependency injection:
public class OrderService
{
private readonly ILogger _logger;
public OrderService(ILogger logger)
{
_logger = logger;
}
public void PlaceOrder(int orderId)
{
_logger.Information("Order {OrderId} placed successfully", orderId);
}
}
Log Levels in Serilog
Serilog supports standard log levels:
| Level | Usage |
|---|---|
| Verbose | Very detailed debugging |
| Debug | Development debugging |
| Information | Normal application flow |
| Warning | Unexpected but handled issues |
| Error | Failures needing attention |
| Fatal | Application crash |
Example:
Log.Warning("Payment retry for OrderId {OrderId}", orderId);
Log.Error(ex, "Payment failed");
Enriching Logs with Context
Serilog allows adding global properties:
Log.Logger = new LoggerConfiguration()
.Enrich.WithProperty("Application", "BlogPortal")
.Enrich.WithProperty("Environment", "Production")
.WriteTo.File("Logs/app.log")
.CreateLogger();
Or per request:
using (LogContext.PushProperty("UserId", userId))
{
Log.Information("User action performed");
}
Now every log inside that scope includes UserId.
Logging Exceptions Properly
Bad logging:
Log.Error(ex.Message);
Good logging:
Log.Error(ex, "Error occurred while processing order {OrderId}", orderId);
This preserves:
- Stack trace
- Inner exceptions
- Context data
Serilog vs Traditional Logging
| Feature | Traditional Logging | Serilog |
|---|---|---|
| Structured data | NO | Yes |
| Searchable logs | NO | Yes |
| Multiple sinks | Limited | Extensive |
| JSON support | NO | Yes |
| Cloud-ready | NO | Yes |
Best Practices for Using Serilog
- Don’t log sensitive data (passwords, tokens)
- Use structured properties, not string concatenation
- Set log levels correctly (avoid
Verbosein production) - Use rolling files or centralized log storage
- Always flush logs on shutdown
When Should You Use Serilog?
Serilog is ideal when:
- You build production-grade .NET apps
- You need searchable logs
- You use ELK / Seq / Azure / AWS logging
- You care about debugging and observability
- In short—almost always.
Final Thoughts
Serilog turns logging from an afterthought into a powerful debugging and monitoring tool. Its structured approach, rich ecosystem of sinks, and excellent performance make it one of the best logging solutions for modern .NET applications.