Serilog.AspNetCore setup for unified ASP.NET Core logging
Serilog integration for ASP.NET Core
At a glance
- What is it?
- Serilog.AspNetCore connects ASP.NET Core and application logs to one Serilog pipeline, with middleware for compact HTTP request events. It suits services that already use Serilog sinks or want structured application and framework logging in one place.
- Who is it for?
- Adopt Serilog.AspNetCore when an ASP.NET Core service needs framework and application events to share Serilog levels and sinks, or when compact HTTP completion records matter. Do not adopt it solely to replace Microsoft ILogger with another ILogger abstraction, since that is what ASP.NET Core already provides.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 67 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why Serilog.AspNetCore unifies two logging paths
ASP.NET Core normally produces its own framework events while application code can write through injected ILogger instances. Serilog.AspNetCore addresses the resulting split by connecting both paths to the same Serilog implementation. The README states that after configuration, developers can write either directly through Serilog or through any ILogger interface injected by ASP.NET, and those loggers share levels and destinations.
The concrete benefit is configuration control at a point that ordinary logging abstractions do not provide by themselves. A developer can select Serilog sinks, apply level overrides, and send framework and application events through the same destination configuration. This is useful when logs are shipped to a system that depends on structured events rather than lines assembled independently by several providers.
The package is primarily for developers maintaining an ASP.NET Core service with Serilog already selected. It is also relevant to teams replacing scattered logging-provider configuration with a central Serilog pipeline. It does not create an application logger from scratch. The first use still requires a LoggerConfiguration, a destination such as the console sink, and startup code that calls AddSerilog().
AddSerilog startup flow in Program.cs
The repository's documented startup sequence configures Log.Logger before the host is built. It then creates the WebApplication, registers Serilog through builder.Services.AddSerilog(), builds the application, maps a route, and runs the host. The try, catch, and finally blocks keep startup and termination exceptions in the Serilog pipeline and call Log.CloseAndFlush() before the process exits.
That ordering matters. The README explicitly places AddSerilog() before builder.Build(). The call redirects log events through the configured Serilog pipeline, but it does not define the pipeline's sinks by itself. In the documented example, the logger has already been created with WriteTo.Console(). A project using files, databases, or another sink would need a different Serilog configuration, which the repository's basic example does not specify.
The sample also maps a root endpoint that returns "Hello World!". Running the sample under a suitable development launch profile should produce the startup messages, the hosting environment, and an HTTP request record once the endpoint is visited. The exact URL and launch behavior are not documented in the README, so they should not be assumed for another project.
Install and run the documented ASP.NET Core sample
Install the package into an existing ASP.NET Core project with the command documented by the repository. This adds the Serilog.AspNetCore package reference to the project. Package version selection still requires care because the README says major versions track Microsoft.Extensions.Hosting and target framework support.
dotnet add package Serilog.AspNetCoreAfter installation, replace the relevant Program.cs setup with the documented flow below. It configures the console sink, registers AddSerilog(), exposes the sample root endpoint, and ensures that Serilog is closed and flushed.
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting web application");
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSerilog();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}Start the application through its normal ASP.NET Core run configuration, then request the configured root URL. The README shows output such as a listening message, a hosting environment line, and an HTTP GET record. It also recommends removing the remaining default logger configuration, including the "Logging" section from appsettings.*.json, after Serilog has replaced it.
Compact HTTP request logging and middleware order
The package includes UseSerilogRequestLogging(), which condenses several ASP.NET Core request-related events into one completion event. According to the README, the resulting event carries the HTTP method, request path, status code, and elapsed time. A text sink can render it as a line similar to "HTTP GET / responded 200 in 227.3253 ms", while a structured formatter can retain those values as separate properties.
This middleware is opt-in. Adding it requires suppressing the noisier default framework sources by setting the minimum levels for Microsoft.AspNetCore.Hosting, Microsoft.AspNetCore.Mvc, and Microsoft.AspNetCore.Routing to Warning. Without those overrides, enabling the condensed event does not remove the existing framework events.
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)Pipeline placement is a real limitation. UseSerilogRequestLogging() must appear before handlers such as MVC, or it will not time or log components placed ahead of it. The same ordering can be useful: placing the middleware after UseStaticFiles() excludes that earlier component from its timing and log coverage. A deployment can therefore produce accurate timing for part of the pipeline while silently omitting earlier middleware, so pipeline order needs to match the question the team expects request logs to answer.
Attach request properties through IDiagnosticContext
A request completion event can carry application-specific measurements without forcing each controller action to emit another log event. The README shows IDiagnosticContext being injected into a controller and Set("CatalogLoadTime", 1423) assigning a property that will appear on the completion event.
public class HomeController : Controller
{
readonly IDiagnosticContext _diagnosticContext;
public HomeController(IDiagnosticContext diagnosticContext)
{
_diagnosticContext = diagnosticContext ??
throw new ArgumentNullException(nameof(diagnosticContext));
}
public IActionResult Index()
{
_diagnosticContext.Set("CatalogLoadTime", 1423);
return View();
}
}This design reduces the number of separate events that must be constructed, transmitted, and stored for a request. It also groups request data into the same event, which can make correlation easier when using a structured sink. The trade-off is that these values are request completion metadata, not automatically emitted as standalone log records. The README does not document behavior for conflicting property names, persistence of diagnostic values across requests, or how a sink handles each property type, so applications should not assume more than the documented Set() behavior.
The default properties are RequestMethod, RequestPath, StatusCode, and Elapsed. The options callback can change the message template, add properties, or alter the event level.
Versioning, licensing, and maintenance signals
Serilog.AspNetCore is distributed under Apache-2.0. That license governs use and redistribution of the package, subject to its terms, but this review does not provide legal advice. Teams adopting it still need to account for their own application code, Serilog packages, sinks, and third-party dependencies.
Maintenance is supported by repository metadata. The project is not archived, and the last push was on 2026-08-17. Recent releases include v10.0.0 on 2025-11-28, v9.0.0 on 2024-12-09, and v8.0.3 on 2024-10-11. These dates show recent release activity, but they do not by themselves define an application's upgrade cost.
The main upgrade constraint is alignment rather than source-level compatibility claims. The README says the package follows Microsoft.Extensions.Hosting versioning and target framework support. Its examples map .NET 7.x to a 7.x package and .NET 8.x to an 8.x package. A new .NET application should therefore select the corresponding Serilog.AspNetCore major version rather than copying an old package reference from a sample. The README does not document a rollback procedure, migration script, or compatibility matrix beyond that version-matching rule.
Serilog.AspNetCore versus ASP.NET Core default ILogger configuration
ASP.NET Core's built-in logging through ILogger is the practical alternative when the application only needs the framework's provider model and Microsoft logging configuration. That approach keeps application and framework logging on the native logging abstractions without requiring Serilog.AspNetCore to redirect them.
Serilog.AspNetCore makes sense when sink selection and structured Serilog behavior are central requirements. It gives injected ILogger callers access to the Serilog pipeline already configured by the application and adds middleware that represents an HTTP request as one event. The repository's sample can then replace the default Logging section with Serilog configuration, which the README links to serilog-settings-configuration and a fuller Sample project.
The cost is dependency and configuration work. Startup code must create Log.Logger, call AddSerilog(), maintain the try, catch, and finally lifecycle, and remove obsolete default logger settings. Request logging also requires framework source overrides and careful middleware placement. ASP.NET Core default logging is the simpler choice when those requirements do not apply; Serilog.AspNetCore is more relevant when one Serilog sink graph should carry both application and framework events.
Editorial conclusion
Adopt Serilog.AspNetCore when an ASP.NET Core service needs framework and application events to share Serilog levels and sinks, or when compact HTTP completion records matter. Do not adopt it solely to replace Microsoft ILogger with another ILogger abstraction, since that is what ASP.NET Core already provides. Before upgrading, first verify that the selected Serilog.AspNetCore major version matches the application's target framework and Microsoft.Extensions.Hosting compatibility, then inspect the middleware position and any retained Logging configuration in appsettings.*.json.
Frequently asked questions
Which Serilog.AspNetCore version should an ASP.NET Core project use?
Choose the version that matches the application's target framework and Microsoft.Extensions.Hosting support. The README gives .NET 7.x with a 7.x package and .NET 8.x with an 8.x package as examples.
How do I enable Serilog request logging in ASP.NET Core?
Call UseSerilogRequestLogging() before handlers such as MVC, and raise the minimum levels of the documented Microsoft.AspNetCore framework sources to Warning to suppress their noisier default events.
Does Serilog.AspNetCore replace the default ASP.NET Core logger configuration?
The README recommends removing the remaining default logger configuration, including the "Logging" section in appsettings.*.json, after Serilog is configured. Serilog configuration can replace it when required.
What does Serilog.AspNetCore add to an HTTP request log event?
Its middleware produces one completion event with RequestMethod, RequestPath, StatusCode, and Elapsed by default. Code can add properties with IDiagnosticContext.Set(), and the options callback can change the template, properties, or level.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/serilog-serilog-aspnetcore)Was this useful?