WideEvents.AspNetCore
0.2.3
See the version list below for details.
dotnet add package WideEvents.AspNetCore --version 0.2.3
NuGet\Install-Package WideEvents.AspNetCore -Version 0.2.3
<PackageReference Include="WideEvents.AspNetCore" Version="0.2.3" />
<PackageVersion Include="WideEvents.AspNetCore" Version="0.2.3" />
<PackageReference Include="WideEvents.AspNetCore" />
paket add WideEvents.AspNetCore --version 0.2.3
#r "nuget: WideEvents.AspNetCore, 0.2.3"
#:package WideEvents.AspNetCore@0.2.3
#addin nuget:?package=WideEvents.AspNetCore&version=0.2.3
#tool nuget:?package=WideEvents.AspNetCore&version=0.2.3
WideEvents
WideEvents is a .NET library for wide events (also known as canonical log lines).
Instead of scattering many log lines across a request, you accumulate context into a single rich, structured event and emit it once at the end.
Heavily inspired by loggingsucks.com and Stripe's canonical log lines.
The problem
A single HTTP request typically produces:
Request started
Loading cart for user_456
Calling payment provider stripe
Retrying payment (attempt 2)
Payment failed: card_declined
Request finished with 500
Six lines. Fragmented context. Expensive to correlate.
The solution
WideEvents accumulates all context and emits one structured event:
{
"http": { "method": "GET", "path": "/checkout/user_456", "status_code": 200 },
"user": { "id": "user_456" },
"payment": { "method": "card", "provider": "stripe" },
"duration_ms": 29.52,
"trace_id": "23ca1dc84f7b4cc4b44b7717ca231c2b",
"span_id": "2454b21b523f02f4",
"trace_flags": "None"
}
One event. Full context.
Packages
| Package | Description |
|---|---|
WideEvents.Abstractions |
IWideEventContext and IWideEventExporter contracts. |
WideEvents.Core |
WideEvent static accumulator and WideEventContext. |
WideEvents.AspNetCore |
Middleware that emits one wide event per HTTP request. |
Targets net8.0 and net10.0.
Installation
# ASP.NET Core apps (brings in Core and Abstractions transitively)
dotnet add package WideEvents.AspNetCore
# Non-web or console apps
dotnet add package WideEvents.Core
Quick start (ASP.NET Core)
Register the middleware and call WideEvent.Add anywhere in the request pipeline:
using WideEvents.AspNetCore;
using WideEvents.Core.Context;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseWideEvents(); // emit one wide event per request
app.MapGet("/checkout/{userId}", (string userId) =>
{
WideEvent.Add("user.id", userId);
WideEvent.Add("payment.method", "card");
WideEvent.Add("payment.provider", "stripe");
return Results.Ok();
});
app.Run();
The middleware automatically adds http.method, http.path, http.status_code, duration_ms, and — when Activity.Current is set — trace_id, span_id, trace_flags.
On unhandled exceptions it captures error.type and error.message instead of http.status_code.
Dotted keys → nested JSON
Dotted key names are expanded into nested objects when the event is built:
WideEvent.Add("payment.method", "card");
WideEvent.Add("payment.provider", "stripe");
{
"payment": {
"method": "card",
"provider": "stripe"
}
}
Duplicate keys overwrite the previous value. null values are ignored. Empty or whitespace keys throw ArgumentException.
Using without ASP.NET Core
using WideEvents.Core.Context;
WideEvent.Add("job.name", "invoice-sync");
WideEvent.Add("job.records", 142);
var evt = WideEvent.Current.Build(); // IReadOnlyDictionary<string, object?>
// ... send evt to your logger or exporter
WideEvent.Reset();
Structured log output
The middleware logs via ILogger using {@WideEvent}. The default .NET console logger serializes dictionaries as ToString() — to get proper nested JSON you need a structured logger that supports destructuring, such as Serilog:
builder.Host.UseSerilog((ctx, lc) => lc
.WriteTo.Console(new PrettyJsonFormatter()));
A runnable sample with Serilog lives in sample/WideEvents.Sample.Api.
Custom exporters
IWideEventExporter is the contract for custom destinations. It is not consumed by the middleware yet — today the middleware emits via ILogger. The interface exists so exporter packages can build against a stable contract:
public class MyExporter : IWideEventExporter
{
public Task ExportAsync(
IReadOnlyDictionary<string, object?> wideEvent,
CancellationToken cancellationToken = default)
{
// send to OTLP, Kafka, ClickHouse, stdout, ...
return Task.CompletedTask;
}
}
Documentation
Full documentation in docs/:
License
Licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. 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. |
-
net10.0
- WideEvents.Core (>= 0.2.3)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
- WideEvents.Core (>= 0.2.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.2.4 | 166 | 6/16/2026 |
| 0.2.3 | 132 | 5/28/2026 |
| 0.2.2 | 121 | 5/28/2026 |
| 0.2.1 | 112 | 5/26/2026 |
| 0.1.0-alpha.0.69 | 72 | 6/30/2026 |