Setting up Serilog in .NET 6
TL;DR: check out the complete, full-featured sample on GitHub.
.NET 6 is officially here! A lot has changed under the hood, and if you're kicking off a new project, a lot has changed on the surface, too.
For starters, a minimal ASP.NET Core application created using
dotnet new web:
- Doesn't have an explicit
Startupclass, or even a
- Uses the new
Everything we know and love is still tucked away in there, but even simple tasks like configuring Serilog have changed enough to warrant some updated instructions.
Why use Serilog with .NET 6?
Is Serilog still relevant in a .NET 6 application? If all you want to do with your logs is view some text in the terminal, maybe not.
If you want to treat your logs as structured data — a stream of first-class events that instrument your application and drive observability — absolutely, Serilog is still where it's at. Serilog has an unbeatable selection of output destinations (sinks), and its ability to enrich, route, filter, and format structured log events make Serilog indispensable in real-world applications.
.NET 6's logging APIs and frameworks can produce rich structured data that's great for production diagnostics and analysis. Serilog is how all of this magic is unlocked.
This post will show the bare minimum Serilog + .NET 6 configuration that you can start using right away. We've expanded it into a complete sample with everything you're likely to need for a production deployment in the
datalust/dotnet6-serilog-example GitHub repository.
You'll need the .NET 6 SDK to get any further. Run
dotnet --version at the terminal to confirm which version you have, if you're unsure.
Projects produced by the
dotnet new web command have a CSPROJ, a configuration file, and a very simple Program.cs that looks like this:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Well that's certainly different!
Adding the Serilog package
To get started you'll need Serilog.AspNetCore:
dotnet add package Serilog.AspNetCore
This includes the core Serilog package, integration into the ASP.NET Core configuration and hosting infrastructure, basic sinks (outputs), and middleware for improved request logging.
You'll also need packages for your preferred sinks. For Seq it's:
dotnet add package Serilog.Sinks.Seq
If you're familiar with Serilog configuration in .NET 5, the first thing you'll try to do is call
using Serilog; var builder = WebApplication.CreateBuilder(args) .UseSerilog(...); // Error CS1929 : 'WebApplicationBuilder' does not contain a definition for 'UseSerilog' and // the best extension method overload 'SerilogWebHostBuilderExtensions.UseSerilog( // IWebHostBuilder, ILogger, bool, LoggerProviderCollection)' requires a receiver of type // 'IWebHostBuilder'
Nope! Cheese moved 🐁.
IHostBuilder we need is in
var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog((ctx, lc) => lc .WriteTo.Console() .WriteTo.Seq("http://localhost:5341")); var app = builder.Build();
And that's enough to get nice Serilog output to the terminal, and structured logs into Seq.
lc argument opens up the rest of the Serilog configuration API, so you can easily enrich your log events with additional properties and send events to more sinks.
Look out! The
builder.WebHost property looks very similar to
builder.Host , and also exposes a
UseSerilog() method, but this is a legacy integration point and it won't behave as nicely as the newer API.
Completing the picture
You can find a full-featured example showing how to handle startup errors, flushing on exit, streamlined request logging, JSON configuration, centralized logging with Seq, rolling file logging, filtering, and more in the sample GitHub repository.
If you're interested in learning more about the startup and hosting changes in .NET 6, check out this fantastic post by Andrew Lock.