Serilog.Sinks.Async 2.1.0

Prefix Reserved
dotnet add package Serilog.Sinks.Async --version 2.1.0                
NuGet\Install-Package Serilog.Sinks.Async -Version 2.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Serilog.Sinks.Async --version 2.1.0                
#r "nuget: Serilog.Sinks.Async, 2.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Serilog.Sinks.Async as a Cake Addin
#addin nuget:?package=Serilog.Sinks.Async&version=2.1.0

// Install Serilog.Sinks.Async as a Cake Tool
#tool nuget:?package=Serilog.Sinks.Async&version=2.1.0                

Serilog.Sinks.Async Build status NuGet

An asynchronous wrapper for other Serilog sinks. Use this sink to reduce the overhead of logging calls by delegating work to a background thread. This is especially suited to non-batching sinks like the File and RollingFile sinks that may be affected by I/O bottlenecks.

Note: many of the network-based sinks (CouchDB, Elasticsearch, MongoDB, Seq, Splunk...) already perform asynchronous batching natively and do not benefit from this wrapper.

Getting started

Install from NuGet:

dotnet add package Serilog.Sinks.Async

Assuming you have already installed the target sink, such as the file sink, move the wrapped sink's configuration within a WriteTo.Async() statement:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Async(a => a.File("logs/myapp.log"))
    // Other logger configuration
    .CreateLogger()

Log.Information("This will be written to disk on the worker thread");

// At application shutdown (results in monitors getting StopMonitoring calls)
Log.CloseAndFlush();

The wrapped sink (File in this case) will be invoked on a worker thread while your application's thread gets on with more important stuff.

Because the memory buffer may contain events that have not yet been written to the target sink, it is important to call Log.CloseAndFlush() or Logger.Dispose() when the application exits.

Buffering & Dropping

The default memory buffer feeding the worker thread is capped to 10,000 items, after which arriving events will be dropped. To increase or decrease this limit, specify it when configuring the async sink. One can determine whether events have been dropped via Serilog.Async.IAsyncLogEventSinkInspector.DroppedMessagesCount (see Sink State Inspection interface below).

// Reduce the buffer to 500 events
.WriteTo.Async(a => a.File("logs/myapp.log"), bufferSize: 500)

Health Monitoring via the Monitor and Inspector interfaces

The Async wrapper is primarily intended to allow one to achieve minimal logging latency at all times, even when writing to sinks that may momentarily block during the course of their processing (e.g., a File Sink might block for a low number of ms while flushing). The dropping behavior is an important failsafe; it avoids having an unbounded buffering behaviour should logging throughput overwhelm the sink, or the sink ingestion throughput degrade.

In practice, this configuration (assuming one provisions an adequate bufferSize) achieves an efficient and resilient logging configuration that can safely handle load without impacting processing throughput. The risk is of course that events get be dropped if the buffer threshold gets breached. The inspection interface, IAsyncLogEventSinkInspector (obtained by providing an IAsyncLogEventSinkMonitor when configuring the Async Sink), enables a health monitoring mechanism to actively validate that the buffer allocation is not being exceeded in practice.

// Example check: log message to an out of band alarm channel if logging is showing signs of getting overwhelmed
void ExecuteAsyncBufferCheck(IAsyncLogEventSinkInspector inspector)
{
    var usagePct = inspector.Count * 100 / inspector.BufferSize;
    if (usagePct > 50) SelfLog.WriteLine("Log buffer exceeded {0:p0} usage (limit: {1})", usagePct, inspector.BufferSize);
}

class MonitorConfiguration : IAsyncLogEventSinkMonitor
{
    public void StartMonitoring(IAsyncLogEventSinkInspector inspector) =>
        HealthMonitor.AddPeriodicCheck(() => ExecuteAsyncBufferCheck(inspector));

    public void StopMonitoring(IAsyncLogEventSinkInspector inspector) 
    { /* reverse of StartMonitoring */ }
}

// Provide monitor so we can wire the health check to the inspector
var monitor = new MonitorConfiguration();
// Use default config (drop events if >10,000 backlog)
.WriteTo.Async(a => a.File("logs/myapp.log"), monitor: monitor) ...

Blocking

Warning: For the same reason one typically does not want exceptions from logging to leak into the execution path, one typically does not want a logger to be able to have the side-effect of actually interrupting application processing until the log propagation has been unblocked.

When the buffer size limit is reached, the default behavior is to drop any further attempted writes until the queue abates, reporting each such failure to the Serilog.Debugging.SelfLog. To replace this with a blocking behaviour, set blockWhenFull to true.

// Wait for any queued event to be accepted by the `File` log before allowing the calling thread to resume its
// application work after a logging call when there are 10,000 LogEvents awaiting ingestion by the pipeline
.WriteTo.Async(a => a.File("logs/myapp.log"), blockWhenFull: true)

XML <appSettings> and JSON configuration

Using Serilog.Settings.Configuration JSON:

{
  "Serilog": {
    "WriteTo": [{
      "Name": "Async",
      "Args": {
        "configure": [{
          "Name": "Console"
        }]
      }
    }]
  }
}

XML configuration support has not yet been added for this wrapper.

About this sink

This sink was created following this conversation thread: https://github.com/serilog/serilog/issues/809.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 is compatible.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (366)

Showing the top 5 NuGet packages that depend on Serilog.Sinks.Async:

Package Downloads
Serilog.Extensions.Logging.File

Add file logging to ASP.NET Core apps with one line of code.

Umbraco.Cms.Infrastructure

Contains the infrastructure assembly needed to run Umbraco CMS.

UmbracoCms.Core

Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms package to setup Umbraco in Visual Studio as an ASP.NET project.

SkyAPM.Utilities.Logging

Microsoft.Utilities.Logging support for SkyAPM.

CG.SharedEntities

Package Description

GitHub repositories (94)

Showing the top 5 popular GitHub repositories that depend on Serilog.Sinks.Async:

Repository Stars
jellyfin/jellyfin
The Free Software Media System
netchx/netch
A simple proxy client
abpframework/abp
Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
felixse/FluentTerminal
A Terminal Emulator based on UWP and web technologies.
EventStore/EventStore
EventStoreDB, the event-native database. Designed for Event Sourcing, Event-Driven, and Microservices architectures
Version Downloads Last updated
2.1.0 364,320 10/24/2024
2.1.0-dev-00098 223 10/23/2024
2.1.0-dev-00096 240 10/21/2024
2.0.0 3,505,762 6/6/2024
2.0.0-dev-00091 155 6/6/2024
1.5.0 59,394,019 6/25/2021
1.5.0-dev-00080 7,500 6/25/2021
1.4.1-dev-00079 15,749 5/13/2021
1.4.1-dev-00073 185,567 5/7/2020
1.4.1-dev-00071 106,463 11/8/2019
1.4.0 28,700,032 6/9/2019
1.4.0-dev-00067 1,452 6/7/2019
1.3.1-dev-00063 68,291 9/22/2018
1.3.1-dev-00061 6,630 8/8/2018
1.3.0 6,094,437 5/21/2018
1.3.0-dev-00056 1,529 5/18/2018
1.2.0 162,935 5/9/2018
1.2.0-dev-00051 1,565 5/9/2018
1.2.0-dev-00049 1,577 5/9/2018
1.2.0-dev-00048 1,778 4/25/2018
1.2.0-dev-00031 1,716 4/19/2018
1.2.0-dev-00018 59,349 8/7/2017
1.1.1-dev-00013 1,902 6/28/2017
1.1.0 15,161,340 6/26/2017
1.0.2-dev-00008 2,523 2/14/2017
1.0.1 729,538 10/17/2016
1.0.1-dev-00004 4,421 8/11/2016
1.0.1-dev-00001 1,783 8/6/2016