solrevdev.Logging.AspNetCore 1.1.0

Prefix Reserved
dotnet add package solrevdev.Logging.AspNetCore --version 1.1.0
                    
NuGet\Install-Package solrevdev.Logging.AspNetCore -Version 1.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="solrevdev.Logging.AspNetCore" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="solrevdev.Logging.AspNetCore" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="solrevdev.Logging.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add solrevdev.Logging.AspNetCore --version 1.1.0
                    
#r "nuget: solrevdev.Logging.AspNetCore, 1.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.
#:package solrevdev.Logging.AspNetCore@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=solrevdev.Logging.AspNetCore&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=solrevdev.Logging.AspNetCore&version=1.1.0
                    
Install as a Cake Tool

Solrevdev.Logging.AspNetCore

Shared Serilog request logging for ASP.NET Core. Several applications write into one Seq server, are told apart by an Application property, and use the same property names so one query means the same thing across all of them.

Install:

dotnet add package solrevdev.Logging.AspNetCore

Set up

This package does not configure Serilog. Configure your own logger and include Enrich.FromLogContext(), or the context middleware properties never reach your ordinary application log events.

builder.Services.AddSerilog((services, configuration) => configuration
    .ReadFrom.Configuration(builder.Configuration)
    .ReadFrom.Services(services)
    .Enrich.FromLogContext()
    .WriteTo.Console());

builder.Services.AddSolrevdevRequestLogging();

AddSolrevdevRequestLogging is required. Each of the three Use calls below throws InvalidOperationException at startup without it. Registering options is not enough on its own: IOptions<RequestLogOptions> resolves to a default instance in any host, so an application that forgot the call used to start and run on package defaults it never chose.

Then the middleware, in this order:

app.UseForwardedHeaders();
app.UseSolrevdevClientLogContext(); // ClientIp and TraceId, above anything that short-circuits
app.UseSolrevdevRequestLogging();   // Serilog's request summary
app.UseStaticFiles();
app.UseRouting();
app.UseRateLimiter();
app.UseAuthentication();
app.UseSolrevdevUserLogContext();   // UserId and UserEmail
app.UseAuthorization();

Behind a load balancer, the application must also enable and configure forwarded-header processing itself. app.UseForwardedHeaders() alone reads nothing, because the default ForwardedHeadersOptions.ForwardedHeaders is None. Set ForwardedHeaders, set a ForwardLimit matching the number of hops, and list the peers or networks you trust in KnownProxies or KnownIPNetworks.

What you get

  • ClientIp rendered so a person can read it. A dual-stack socket delivers an IPv4 caller as ::ffff:203.0.113.42 and a local one as ::1, and both become the dotted form. All of 127.0.0.0/8 collapses to 127.0.0.1, a link-local address keeps its zone suffix, and a public IPv6 address passes through untouched rather than being run through MapToIPv4, which silently returns a wrong but plausible IPv4 address.
  • ForwardedFor, a best-effort reconstruction of what the caller claimed. UseForwardedHeaders consumes the entries it accepts, so reading the header afterwards finds a leftover or nothing. This puts the settled address back beside it, which makes a difference visible. It is untrusted and lossy: ports, intermediate hops and the caller's own spelling do not survive. Use it as a clue, never for identity or access.
  • Referer with its query string and fragment removed. Password-reset and email-confirmation tokens ride in query strings, and a browser sends the page it came from as the next request's Referer. This is that one control, not general secret redaction.
  • UserId and UserEmail on every event inside an authenticated request, pushed onto Serilog's LogContext so no call site changes.
  • Static files, /healthcheck and /version demoted to Verbose when they succeed, and left alone when they fail.
  • LoggingContract, the property names as constants and as sets, so each application can test that its own request summaries still carry them.

Properties are omitted rather than set to an empty string. An anonymous request carries no user properties, a request with no Referer carries no Referer, and a claim holding an empty string counts as absent. LoggingContract.OptionalProperties lists the names a legitimate request can arrive without, so a contract test asserts RequiredProperties minus those.

What it deliberately does not do

No rate limiting, no throttling, no ForwardedHeadersOptions policy, and nothing that keys off an address for any purpose other than a log property. Those are the consuming application's decisions.

The address this package renders is reshaped to be readable, which is exactly wrong for a partition key. Never use it for a rate limit, a throttle, a cache partition, an authorisation decision or a stored column. It reads identically to the raw address for every caller arriving in native, non-mapped, non-loopback form, which is what lets that mistake survive testing.

Full documentation: https://github.com/solrevdev/solrevdev.logging

MIT licensed.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.0 55 9/8/2026
1.0.0 52 9/8/2026