What it is
Serilog is a structured logging library for .NET that treats log events as data with named properties rather than formatted strings.
Log messages use named holes rather than interpolation, so each value is captured as a queryable property alongside the rendered text.
Installation
dotnet add package Serilog.AspNetCoreGetting started
The smallest useful thing you can do with it, and what each part means.
csharp
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
// Named holes — NOT string interpolation.
log.Information("Order {OrderId} shipped to {Customer} for {Total:C}",
order.Id, order.Customer, order.Total);
// $"Order {order.Id} shipped" would log one opaque string with no
// queryable properties — this is the single most common mistake.Advanced usage
Where the library earns its place over a simpler alternative.
csharp
// Scope properties onto every event inside the block.
using (LogContext.PushProperty("CorrelationId", correlationId))
{
log.Information("Processing started");
// …everything here carries CorrelationId
}
// @ serialises the object rather than calling ToString().
log.Information("Received {@Order}", order);
// ASP.NET Core: one tidy line per request instead of six.
app.UseSerilogRequestLogging(options =>
{
options.EnrichDiagnosticContext = (ctx, http) =>
ctx.Set("UserId", http.User?.FindFirst("sub")?.Value);
});Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Logs are missing after the process exits
- Buffered sinks were not flushed. Call Log.CloseAndFlush() in a finally block around the host run.
- Properties are not queryable in the log platform
- The message used interpolation. Switch to {Named} holes with arguments.
Best practices
- Use message templates with named holes; never use string interpolation in a log call.
- Override minimum levels per namespace so framework noise does not drown your own events.
- Use @ to destructure objects and never log secrets, tokens or full request bodies.
- Call Log.CloseAndFlush() on shutdown so buffered events are written.
Background
Why it exists, and what it was reacting to.
Created by Nicholas Blumhardt, Serilog introduced structured logging to .NET before the platform had it built in. Its sink ecosystem covers essentially every log destination in use.
