VanDerHeijden.Logging
10.1.0
dotnet add package VanDerHeijden.Logging --version 10.1.0
NuGet\Install-Package VanDerHeijden.Logging -Version 10.1.0
<PackageReference Include="VanDerHeijden.Logging" Version="10.1.0" />
<PackageVersion Include="VanDerHeijden.Logging" Version="10.1.0" />
<PackageReference Include="VanDerHeijden.Logging" />
paket add VanDerHeijden.Logging --version 10.1.0
#r "nuget: VanDerHeijden.Logging, 10.1.0"
#:package VanDerHeijden.Logging@10.1.0
#addin nuget:?package=VanDerHeijden.Logging&version=10.1.0
#tool nuget:?package=VanDerHeijden.Logging&version=10.1.0
VanDerHeijden.Logging
Core abstractions for high-performance batched logging in .NET 10.
What's in this package
LogEntry— the structured log entry shared by all writersLogEntryJsonWriter— sharedUtf8JsonWriter-based JSON serializer forLogEntryIBatchedLogWriter<T>— implement this interface to create a custom log writerBatchedLogger<T>— background consumer that batches entries and calls your writerBatchedLoggerProvider<T>—ILoggerProvideradapter for use withMicrosoft.Extensions.Logging
This package contains no writer implementation. Install one of the writer packages instead:
| Package | Target |
|---|---|
VanDerHeijden.Logging.File |
Daily rotating text files |
VanDerHeijden.Logging.MongoDb |
MongoDB collection |
VanDerHeijden.Logging.Sql |
SQL Server (SqlBulkCopy) |
VanDerHeijden.Logging.Redis |
Redis list (RPUSH) |
Implementing a custom writer
public sealed class MyWriter : IBatchedLogWriter<LogEntry>
{
public async Task WriteBatchAsync(List<LogEntry> entries, CancellationToken ct)
{
// write entries to your target
}
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}
Register it:
builder.Logging.Services.AddSingleton<ILoggerProvider>(sp =>
{
var httpContextAccessor = sp.GetService<IHttpContextAccessor>(); // optional
var writer = new MyWriter();
var logger = new BatchedLogger<LogEntry>(writer, batchSize: 200, maxIdleMs: 4000);
return new BatchedLoggerProvider<LogEntry>(
logger,
entryFactory: entry => entry,
httpContextAccessor);
});
The entryFactory is a Func<LogEntry, T> that runs on the logging thread; return the entry itself or project it
to your own type (for example a pre-formatted string).
LogEntry
| Property | Description |
|---|---|
Timestamp |
DateTime, always UTC |
Level |
LogLevel |
EventId / EventName |
From the EventId passed to the log call |
Category |
Logger category name |
Message |
Formatted message |
MessageTemplate |
The original template ({OriginalFormat}), e.g. User {UserId} logged in |
Properties |
Dictionary<string, object?> with the named template arguments; null when there are none |
Exception |
exception.ToString(), or null |
Path, Method, ClientIp, Referer, UserAgent, SessionId, SessionGuid |
Request metadata; null when no HTTP context is active or IHttpContextAccessor is not registered |
Property values are snapshotted at log time. They keep their type when they are a string, bool, int, long,
double, decimal, Guid or DateTime (converted to UTC); smaller numeric types are widened, enums are stored by
name, and TimeSpan and other formattable values are stored as strings.
Objects, records and collections are stored as nested JSON, so logger.LogInformation("Order for {Customer}", customer)
stores "Customer": { "Name": "Alice", "Number": 7, "Tags": ["vip"] } (a subdocument in MongoDB) instead of the
ToString() text. To keep the logging call cheap, only a shallow clone of the object is taken at log time; the
JSON is produced later, on the background writer thread:
- Top-level members are frozen at log time: changing
customer.Nameafterwards does not affect the log. - Nested objects and collections are shared with the original: changing
customer.Address.Cityor adding tocustomer.Tagsbefore the batch is written can show up in the log. Log immutable data (records) or the specific values you need when that matters. - Objects that must not be cloned — anything
IDisposableor with a finalizer, types, delegates, exceptions, tasks — are stored as theirToString()text, as are values that cannot be serialized, have no public properties or exceed 32 KB of JSON.
Enums inside objects are written by name. The formatted Message is unaffected: it still contains the ToString()
text, as produced by Microsoft.Extensions.Logging.
LogEntryJsonWriter
LogEntryJsonWriter serializes entries with Utf8JsonWriter into a reusable buffer and is the single place where the
JSON field names are defined. It is not thread-safe; use one instance per log writer.
var json = new LogEntryJsonWriter();
json.Clear();
json.WriteLine(entry); // one JSON object + '\n' (JSON Lines)
await stream.WriteAsync(json.WrittenMemory, ct);
json.Clear();
json.WriteProperties(entry.Properties); // only the properties object
string propertiesJson = json.ToString();
Backpressure
BatchedLogger<T> is configured with BatchedLoggerOptions: BatchSize (default 200), MaxIdleMs (4000),
QueueCapacity (10 000) and FullMode (Wait). All writer packages expose the same options.
BatchedLogger<T>.Write honours FullMode. With BoundedChannelFullMode.Wait
(the default) the call blocks while the queue is full, so nothing is dropped; with the drop modes
it never blocks.
Repository
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.13)
- Microsoft.Extensions.Configuration (>= 10.0.12)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.12)
- Microsoft.Extensions.Logging (>= 10.0.12)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Logging.Console (>= 10.0.12)
- Microsoft.Net.Http.Headers (>= 10.0.12)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on VanDerHeijden.Logging:
| Package | Downloads |
|---|---|
|
VanDerHeijden.Logging.MongoDb
MongoDB log writer for VanDerHeijden.Logging: writes batched log entries to a MongoDB collection. |
|
|
VanDerHeijden.Logging.File
File log writer for VanDerHeijden.Logging: writes batched log entries to daily rotating text files. |
|
|
VanDerHeijden.Logging.Redis
Redis log writer for VanDerHeijden.Logging: writes batched log entries to a Redis list using RPUSH. |
|
|
VanDerHeijden.Logging.Sql
SQL Server log writer for VanDerHeijden.Logging: writes batched log entries to a SQL Server table using SqlBulkCopy. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.1.0 | 63 | 9/30/2026 |
| 10.0.11 | 136 | 9/15/2026 |
| 10.0.10 | 96 | 9/15/2026 |
| 10.0.9 | 127 | 9/15/2026 |
| 10.0.8 | 166 | 5/13/2026 |
| 10.0.7 | 159 | 4/9/2026 |
| 10.0.6 | 173 | 3/11/2026 |
| 10.0.5 | 125 | 3/2/2026 |
| 10.0.4 | 158 | 2/23/2026 |
| 10.0.3 | 150 | 2/23/2026 |
| 10.0.2 | 147 | 2/23/2026 |
| 10.0.1 | 155 | 2/23/2026 |
| 10.0.0 | 152 | 2/22/2026 |