Serilog.Extensions.Logging 8.0.1-dev-10373

Serilog.Extensions.Logging Build status NuGet Version

A Serilog provider for Microsoft.Extensions.Logging, the logging subsystem used by ASP.NET Core.

ASP.NET Core Instructions

ASP.NET Core applications should prefer Serilog.AspNetCore and UseSerilog() instead.

Non-web .NET Core Instructions

Non-web .NET Core applications should prefer Serilog.Extensions.Hosting and UseSerilog() instead.

.NET Core 1.0, 1.1 and Default Provider Integration

The package implements AddSerilog() on ILoggingBuilder and ILoggerFactory to enable the Serilog provider under the default Microsoft.Extensions.Logging implementation.

First, install the Serilog.Extensions.Logging NuGet package into your web or console app. You will need a way to view the log messages - Serilog.Sinks.Console writes these to the console.

dotnet add package Serilog.Extensions.Logging
dotnet add package Serilog.Sinks.Console

Next, in your application's Startup method, configure Serilog first:

using Serilog;

public class Startup
{
  public Startup(IHostingEnvironment env)
  {
    Log.Logger = new LoggerConfiguration()
      .Enrich.FromLogContext()
      .WriteTo.Console()
      .CreateLogger();

    // Other startup code

Finally, for .NET Core 2.0+, in your Startup class's Configure() method, remove the existing logger configuration entries and call AddSerilog() on the provided loggingBuilder.

  public void ConfigureServices(IServiceCollection services)
  {
      services.AddLogging(loggingBuilder =>
      	loggingBuilder.AddSerilog(dispose: true));

      // Other services ...
  }

For .NET Core 1.0 or 1.1, in your Startup class's Configure() method, remove the existing logger configuration entries and call AddSerilog() on the provided loggerFactory.

  public void Configure(IApplicationBuilder app,
                        IHostingEnvironment env,
                        ILoggerFactory loggerfactory,
                        IApplicationLifetime appLifetime)
  {
      loggerfactory.AddSerilog();

      // Ensure any buffered events are sent at shutdown
      appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);

That's it! With the level bumped up a little you should see log output like:

[22:14:44.646 DBG] RouteCollection.RouteAsync
	Routes:
		Microsoft.AspNet.Mvc.Routing.AttributeRoute
		{controller=Home}/{action=Index}/{id?}
	Handled? True
[22:14:44.647 DBG] RouterMiddleware.Invoke
	Handled? True
[22:14:45.706 DBG] /lib/jquery/jquery.js not modified
[22:14:45.706 DBG] /css/site.css not modified
[22:14:45.741 DBG] Handled. Status code: 304 File: /css/site.css

Notes on Log Scopes

Microsoft.Extensions.Logging provides the BeginScope API, which can be used to add arbitrary properties to log events within a certain region of code. The API comes in two forms:

  1. The method: IDisposable BeginScope<TState>(TState state)
  2. The extension method: IDisposable BeginScope(this ILogger logger, string messageFormat, params object[] args)

Using the extension method will add a Scope property to your log events. This is most useful for adding simple "scope strings" to your events, as in the following code:

using (_logger.BeginScope("Transaction")) {
    _logger.LogInformation("Beginning...");
    _logger.LogInformation("Completed in {DurationMs}ms...", 30);
}
// Example JSON output:
// {"@t":"2020-10-29T19:05:56.4126822Z","@m":"Beginning...","@i":"f6a328e9","SourceContext":"SomeNamespace.SomeService","Scope":["Transaction"]}
// {"@t":"2020-10-29T19:05:56.4176816Z","@m":"Completed in 30ms...","@i":"51812baa","DurationMs":30,"SourceContext":"SomeNamespace.SomeService","Scope":["Transaction"]}

If you simply want to add a "bag" of additional properties to your log events, however, this extension method approach can be overly verbose. For example, to add TransactionId and ResponseJson properties to your log events, you would have to do something like the following:

// WRONG! Prefer the dictionary approach below instead
using (_logger.BeginScope("TransactionId: {TransactionId}, ResponseJson: {ResponseJson}", 12345, jsonString)) {
    _logger.LogInformation("Completed in {DurationMs}ms...", 30);
}
// Example JSON output:
// {
//	"@t":"2020-10-29T19:05:56.4176816Z",
//	"@m":"Completed in 30ms...",
//	"@i":"51812baa",
//	"DurationMs":30,
//	"SourceContext":"SomeNamespace.SomeService",
//	"TransactionId": 12345,
//	"ResponseJson": "{ \"Key1\": \"Value1\", \"Key2\": \"Value2\" }",
//	"Scope":["TransactionId: 12345, ResponseJson: { \"Key1\": \"Value1\", \"Key2\": \"Value2\" }"]
// }

Not only does this add the unnecessary Scope property to your event, but it also duplicates serialized values between Scope and the intended properties, as you can see here with ResponseJson. If this were "real" JSON like an API response, then a potentially very large block of text would be duplicated within your log event! Moreover, the template string within BeginScope is rather arbitrary when all you want to do is add a bag of properties, and you start mixing enriching concerns with formatting concerns.

A far better alternative is to use the BeginScope<TState>(TState state) method. If you provide any IEnumerable<KeyValuePair<string, object>> to this method, then Serilog will output the key/value pairs as structured properties without the Scope property, as in this example:

var scopeProps = new Dictionary<string, object> {
    { "TransactionId", 12345 },
    { "ResponseJson", jsonString },
};
using (_logger.BeginScope(scopeProps) {
    _logger.LogInformation("Transaction completed in {DurationMs}ms...", 30);
}
// Example JSON output:
// {
//	"@t":"2020-10-29T19:05:56.4176816Z",
//	"@m":"Completed in 30ms...",
//	"@i":"51812baa",
//	"DurationMs":30,
//	"SourceContext":"SomeNamespace.SomeService",
//	"TransactionId": 12345,
//	"ResponseJson": "{ \"Key1\": \"Value1\", \"Key2\": \"Value2\" }"
// }

Versioning

This package tracks the versioning and target framework support of its Microsoft.Extensions.Logging dependency.

Credits

This package evolved from an earlier package Microsoft.Framework.Logging.Serilog provided by the ASP.NET team.

Showing the top 20 packages that depend on Serilog.Extensions.Logging.

Packages Downloads
Serilog.Extensions.Hosting
Serilog support for .NET Core logging in hosted services
30
Serilog.Extensions.Hosting
Serilog support for .NET Core logging in hosted services
19
Serilog.Extensions.Hosting
Serilog support for .NET Core logging in hosted services
17
Serilog.Extensions.Hosting
Serilog support for .NET Core logging in hosted services
16

.NET Framework 4.6.2

.NET 6.0

.NET 7.0

.NET 8.0

.NET Standard 2.0

.NET Standard 2.1

Version Downloads Last updated
10.0.0 10 12/16/2025
10.0.0-dev-02334 9 12/16/2025
9.0.3-dev-02320 11 6/7/2025
9.0.2 15 6/7/2025
9.0.2-dev-02316 14 6/7/2025
9.0.2-dev-02315 14 6/7/2025
9.0.1 15 4/1/2025
9.0.1-dev-02311 14 3/20/2025
9.0.1-dev-02310 14 3/20/2025
9.0.1-dev-02308 15 2/19/2025
9.0.0 17 2/19/2025
9.0.0-dev-02305 14 2/19/2025
9.0.0-dev-02304 15 2/19/2025
9.0.0-dev-02302 16 2/19/2025
9.0.0-dev-02301 16 2/19/2025
8.0.1-dev-10410 16 2/19/2025
8.0.1-dev-10407 15 2/19/2025
8.0.1-dev-10398 16 2/19/2025
8.0.1-dev-10391 15 2/19/2025
8.0.1-dev-10389 16 2/19/2025
8.0.1-dev-10382 16 2/19/2025
8.0.1-dev-10377 12 2/19/2025
8.0.1-dev-10373 16 2/19/2025
8.0.1-dev-10370 15 2/19/2025
8.0.0 17 2/19/2025
8.0.0-dev-10367 17 2/19/2025
8.0.0-dev-10359 15 2/19/2025
7.0.1-dev-10354 18 2/19/2025
7.0.0 20 6/10/2023
7.0.0-dev-10353 15 2/19/2025
7.0.0-dev-10346 16 2/19/2025
3.1.1-dev-10338 16 2/19/2025
3.1.1-dev-10337 16 2/19/2025
3.1.1-dev-10301 15 2/19/2025
3.1.0 19 5/2/2022
3.1.0-dev-10295 17 2/19/2025
3.0.2-dev-10289 17 2/19/2025
3.0.2-dev-10286 17 2/19/2025
3.0.2-dev-10284 16 2/19/2025
3.0.2-dev-10281 16 2/19/2025
3.0.2-dev-10280 16 2/19/2025
3.0.2-dev-10272 15 2/19/2025
3.0.2-dev-10269 16 2/19/2025
3.0.2-dev-10265 15 2/19/2025
3.0.2-dev-10260 15 2/19/2025
3.0.2-dev-10257 16 2/19/2025
3.0.2-dev-10256 17 2/19/2025
3.0.1 27 1/5/2022
3.0.1-dev-10252 14 2/19/2025
3.0.0 17 2/19/2025
3.0.0-dev-10248 16 2/19/2025
3.0.0-dev-10244 15 2/19/2025
3.0.0-dev-10240 16 2/19/2025
3.0.0-dev-10237 15 2/19/2025
3.0.0-dev-10234 15 2/19/2025
3.0.0-dev-10232 17 2/19/2025
2.0.5-dev-10226 14 2/19/2025
2.0.5-dev-10225 14 2/19/2025
2.0.4 17 2/19/2025
2.0.3 17 2/19/2025
2.0.3-dev-10220 15 2/19/2025
2.0.3-dev-10215 14 2/19/2025
2.0.2 15 2/19/2025
2.0.2-dev-10199 15 2/19/2025
2.0.1 17 2/19/2025
2.0.1-dev-10207 15 2/19/2025
2.0.1-dev-10205 17 2/19/2025
2.0.1-dev-10204 15 2/19/2025
2.0.1-dev-10195 15 2/19/2025
2.0.0 15 2/19/2025
2.0.0-dev-10187 15 2/19/2025
2.0.0-dev-10185 15 2/19/2025
2.0.0-dev-10180 16 2/19/2025
2.0.0-dev-10177 15 2/19/2025
2.0.0-dev-10174 15 2/19/2025
2.0.0-dev-10172 15 2/19/2025
2.0.0-dev-10169 15 2/19/2025
2.0.0-dev-10164 17 2/19/2025
1.4.1-dev-10155 16 2/19/2025
1.4.1-dev-10152 14 2/19/2025
1.4.1-dev-10147 16 2/19/2025
1.4.0 17 2/19/2025
1.4.0-dev-10144 16 2/19/2025
1.4.0-dev-10138 12 2/19/2025
1.4.0-dev-10136 15 2/19/2025
1.4.0-dev-10133 15 2/19/2025
1.3.1 15 2/19/2025
1.3.0 17 2/19/2025
1.3.0-dev-10129 15 2/19/2025
1.3.0-dev-10125 15 2/19/2025
1.2.0 17 2/19/2025
1.2.0-dev-10122 15 2/19/2025
1.1.0 16 2/19/2025
1.1.0-dev-10116 15 2/19/2025
1.1.0-dev-10114 15 2/19/2025
1.0.0 16 2/19/2025
1.0.0-rc2-10110 16 2/19/2025
1.0.0-rc2-10108 15 2/19/2025
1.0.0-rc2-10104 16 2/19/2025
1.0.0-rc2-10102 16 2/19/2025
1.0.0-rc2-10099 16 2/19/2025
1.0.0-rc2-10096 17 2/19/2025
1.0.0-rc1-final-10092 15 2/19/2025
1.0.0-rc1-final-10091 16 2/19/2025
1.0.0-rc1-final-10088 14 2/19/2025
1.0.0-rc1-final-10087 15 2/19/2025
1.0.0-rc1-final-10086 15 2/19/2025