Serilog.Sinks.ObservableCollection
2.0.0
dotnet add package Serilog.Sinks.ObservableCollection --version 2.0.0
NuGet\Install-Package Serilog.Sinks.ObservableCollection -Version 2.0.0
<PackageReference Include="Serilog.Sinks.ObservableCollection" Version="2.0.0" />
<PackageVersion Include="Serilog.Sinks.ObservableCollection" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.ObservableCollection" />
paket add Serilog.Sinks.ObservableCollection --version 2.0.0
#r "nuget: Serilog.Sinks.ObservableCollection, 2.0.0"
#:package Serilog.Sinks.ObservableCollection@2.0.0
#addin nuget:?package=Serilog.Sinks.ObservableCollection&version=2.0.0
#tool nuget:?package=Serilog.Sinks.ObservableCollection&version=2.0.0
Serilog.Sinks.ObservableCollection 
The ObservableCollectionSink is a custom Serilog sink designed to log messages to an ObservableCollection, which can be particularly useful in WPF applications where logs need to be displayed in the UI in real-time.
Prerequisites
- Serilog 4.x or later installed in your .NET project (batching support is built-in).
- Access to a dispatcher (typically from a UI context in WPF or similar).
Installation
Ensure Serilog 4.x or later is installed in your project:
Install-Package Serilog
Configuration
Configure the sink within your application's logging setup. Examples are provided for both standard and batched logging setups.
Standard Logging Configuration
var LogEvents = new ObservableCollection<LogEvent>();
Log.Logger = new LoggerConfiguration()
.WriteTo.ObservableCollection(
LogEvents,
dispatcher: action => Application.Current.Dispatcher.Invoke,
configure: options =>
{
options.MaxStoredEvents = 1000; // Maximum log events to store
options.MinimumLevel = LogEventLevel.Information;
})
.CreateLogger();
Batched Logging Configuration
Enable batching by configuring the sink accordingly:
Log.Logger = new LoggerConfiguration()
.WriteTo.ObservableCollection(
LogEvents,
dispatcher: action => dispatcher.Invoke(action),
configure: options =>
{
options.EnableBatching = true;
options.BatchSizeLimit = 50;
options.Period = TimeSpan.FromSeconds(2);
options.MaxStoredEvents = 1000;
options.OnEmptyBatchAction = async () =>
{
// Custom action to perform when no events have been emitted
await Task.Run(() => Debug.WriteLine("No events emitted for the specified period."));
};
})
.CreateLogger();
Dependency Injection Configuration
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddSingleton<ObservableCollection<LogEvent>>();
// other services
})
.UseSerilog((context, services, configuration) =>
{
var logEvents = services.GetRequiredService<ObservableCollection<LogEvent>>();
configuration
.MinimumLevel.Debug() // Set the global minimum level to Debug
.WriteTo.ObservableCollection(logEvents, Application.Current.Dispatcher.Invoke, options =>
{
options.MaxStoredEvents = 1000;
options.EnableBatching = true;
options.BatchSizeLimit = 50;
options.Period = TimeSpan.FromSeconds(2);
options.MinimumLevel = LogEventLevel.Information; // set the minimum level for the ObservableCollection sink to Information
options.OnEmptyBatchAction = async () =>
{
// Custom action to perform when no events have been emitted for a certain period of time
await Task.Run(() => Debug.WriteLine("No events emitted for the specified period."));
};
});
})
.Build();
Usage
Once configured, use the sink like any other Serilog sink:
Log.Information("This is a test log message.");
Examples of viewing logs in a WPF application are provided in the sample project.
Disposal
Remember to properly dispose of your loggers when the application is closing:
Log.CloseAndFlush();
This is especially important in batched mode to ensure all pending log messages are flushed to the UI.
Additional Notes
- Ensure the dispatcher is suitable for the thread managing the UI component to avoid cross-thread operations.
- MaxStoredEvents helps manage memory by limiting the number of log events stored. Adjust based on performance needs.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.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 was computed. net463 was computed. net47 was computed. net471 was computed. 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. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.