Serilog.Enrichers.HttpContext
8.3.0
See the version list below for details.
dotnet add package Serilog.Enrichers.HttpContext --version 8.3.0
NuGet\Install-Package Serilog.Enrichers.HttpContext -Version 8.3.0
<PackageReference Include="Serilog.Enrichers.HttpContext" Version="8.3.0" />
<PackageVersion Include="Serilog.Enrichers.HttpContext" Version="8.3.0" />
<PackageReference Include="Serilog.Enrichers.HttpContext" />
paket add Serilog.Enrichers.HttpContext --version 8.3.0
#r "nuget: Serilog.Enrichers.HttpContext, 8.3.0"
#:package Serilog.Enrichers.HttpContext@8.3.0
#addin nuget:?package=Serilog.Enrichers.HttpContext&version=8.3.0
#tool nuget:?package=Serilog.Enrichers.HttpContext&version=8.3.0
Serilog.Enrichers.HttpContext 
Enriches Serilog events with client IP, RequestBody, RequestQuery, HTTP request headers and memory usage. Correlation Id can be added via WithRequestHeader("X-Correlation-Id", "CorrelationId").
Supported frameworks: .NET Standard 2.1, .NET 6, .NET 7, .NET 8, .NET 9, .NET 10
Install the Serilog.Enrichers.HttpContext NuGet package
Install-Package Serilog.Enrichers.HttpContext
or
dotnet add package Serilog.Enrichers.HttpContext
Apply the enricher to your LoggerConfiguration in code:
Log.Logger = new LoggerConfiguration()
.Enrich.WithClientIp()
.Enrich.WithMemoryUsage()
.Enrich.WithMemoryUsageExact()
.Enrich.WithRequestBody()
.Enrich.WithRequestQuery()
.Enrich.WithRequestHeader("Header-Name1")
// ...other configuration...
.CreateLogger();
or in appsettings.json file (requires Serilog.Settings.Configuration or Serilog.AspNetCore):
{
"Serilog": {
"MinimumLevel": "Verbose",
"Using": [ "Serilog.Enrichers.HttpContext" ],
"Enrich": [
"WithClientIp",
"WithMemoryUsage",
"WithMemoryUsageExact",
"WithRequestBody",
"WithRequestQuery",
{
"Name": "WithRequestHeader",
"Args": {
"headerName": "X-Correlation-Id",
"propertyName": "CorrelationId"
}
},
{
"Name": "WithRequestHeader",
"Args": { "headerName": "User-Agent" }
}
],
"WriteTo": [
{ "Name": "Console" }
]
}
}
Enricher Configuration
WithClientIp
Adds the ClientIp property — client IP address. By default uses "x-forwarded-for" header. When behind a proxy, uses the configured header to determine the real IP. Returns "unknown" when the IP cannot be determined.
| Parameter | Type | Default | Description |
|---|---|---|---|
headerName |
string | "x-forwarded-for" |
Proxy header name containing the IP address |
Code:
.Enrich.WithClientIp()
.Enrich.WithClientIp(headerName: "CF-Connecting-IP")
appsettings.json:
"WithClientIp"
or with parameters:
{
"Name": "WithClientIp",
"Args": { "headerName": "CF-Connecting-IP" }
}
Full example for custom proxy header:
{
"Serilog": {
"MinimumLevel": "Verbose",
"Using": [ "Serilog.Enrichers.HttpContext" ],
"Enrich": [
{
"Name": "WithClientIp",
"Args": { "headerName": "CF-Connecting-IP" }
}
],
"WriteTo": [ { "Name": "Console" } ]
}
}
WithMemoryUsage
Adds the MemoryUsage property — process memory usage in bytes. Works in any context (does not require HTTP request).
Code:
.Enrich.WithMemoryUsage()
appsettings.json:
"WithMemoryUsage"
WithMemoryUsageExact
Adds the MemoryUsageExact property — memory increase since the start of the request (in bytes).
Required: You must add app.UseSerilogMemoryUsageExact() middleware to the pipeline. Place it early, before request handlers (e.g. MapGet, MapControllers).
Enricher registration
Code:
.Enrich.WithMemoryUsageExact()
appsettings.json:
"WithMemoryUsageExact"
Middleware registration
Program.cs (minimal hosting):
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services));
var app = builder.Build();
app.UseSerilogMemoryUsageExact();
app.MapGet("/", () => "Hello");
app.Run();
Startup.cs (in Configure method):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddSerilog();
app.UseSerilogMemoryUsageExact();
app.UseRouting();
app.UseEndpoints(endpoints => { /* ... */ });
}
WithRequestBody
Adds the RequestBody property — HTTP request body. Note: If controllers or model binding read the body before logging, add middleware at the start of the pipeline to enable buffering:
app.Use(async (context, next) =>
{
context.Request.EnableBuffering();
await next();
});
Code:
.Enrich.WithRequestBody()
appsettings.json:
"WithRequestBody"
WithRequestQuery
Adds the RequestQuery property — HTTP request query string.
Code:
.Enrich.WithRequestQuery()
appsettings.json:
"WithRequestQuery"
WithRequestHeader
You can use multiple WithRequestHeader to log different request headers. WithRequestHeader accepts two parameters: the first parameter headerName is the header name to log, and the second parameter propertyName is the log property name.
| Parameter | Type | Required | Description |
|---|---|---|---|
headerName |
string | yes | HTTP header name |
propertyName |
string | no | Log property name (if not specified — headerName without hyphens) |
When the header is absent, the property value is null.
Code:
.Enrich.WithRequestHeader("User-Agent")
.Enrich.WithRequestHeader(headerName: "Content-Length", propertyName: "RequestLength")
.Enrich.WithRequestHeader("X-Correlation-Id", "CorrelationId")
appsettings.json:
{
"Name": "WithRequestHeader",
"Args": { "headerName": "User-Agent" }
}
or with custom property name:
{
"Name": "WithRequestHeader",
"Args": {
"headerName": "X-Correlation-Id",
"propertyName": "CorrelationId"
}
}
Full example with multiple headers:
{
"Serilog": {
"MinimumLevel": "Verbose",
"Using": [ "Serilog.Enrichers.HttpContext" ],
"Enrich": [
{ "Name": "WithRequestHeader", "Args": { "headerName": "User-Agent" } },
{ "Name": "WithRequestHeader", "Args": { "headerName": "header-name" } },
{
"Name": "WithRequestHeader",
"Args": {
"headerName": "Content-Length",
"propertyName": "RequestLength"
}
}
],
"WriteTo": [ { "Name": "Console" } ]
}
}
Note
To include logged headers in OutputTemplate, the header name without - should be used if you haven't set the log property name. For example, if the header name is User-Agent, you should use UserAgent.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.WithRequestHeader("User-Agent")
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss}] {Level:u3} {UserAgent} {Message:lj}{NewLine}{Exception}")
Installing into an ASP.NET Core Web Application
You need to register the IHttpContextAccessor singleton so the enrichers have access to the requests HttpContext. Without it, WithClientIp, WithRequestBody, WithRequestQuery, WithRequestHeader, and WithMemoryUsageExact will not add properties when logging outside a request context or when HttpContext is unavailable.
If you use WithMemoryUsageExact, you must add the app.UseSerilogMemoryUsageExact() middleware early in the pipeline (before request handlers) to capture memory at the start of each request.
This is what your Startup class should contain in order for this enricher to work as expected:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
namespace MyWebApp
{
public class Startup
{
public Startup()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss}] {Level:u3} Client IP: {ClientIp} Correlation Id: {CorrelationId} header-name: {headername} {Message:lj}{NewLine}{Exception}")
.Enrich.WithClientIp()
.Enrich.WithMemoryUsage()
.Enrich.WithMemoryUsageExact()
.Enrich.WithRequestBody()
.Enrich.WithRequestQuery()
.Enrich.WithRequestHeader("header-name")
.Enrich.WithRequestHeader("another-header-name", "AnotherHeaderNameNewName")
.CreateLogger();
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHttpContextAccessor();
// ...
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
// ...
loggerFactory.AddSerilog();
app.UseSerilogMemoryUsageExact(); // Required for WithMemoryUsageExact enricher
// ...
}
}
}
For minimal hosting (Program.cs with WebApplication):
builder.Services.AddHttpContextAccessor();
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services));
var app = builder.Build();
// ...
app.UseSerilogMemoryUsageExact(); // Required for WithMemoryUsageExact enricher
// ...
app.Run();
| Product | Versions 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 is compatible. 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. net9.0 is compatible. 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 | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | 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 (5)
Showing the top 5 NuGet packages that depend on Serilog.Enrichers.HttpContext:
| Package | Downloads |
|---|---|
|
Aj.Platform.Core
Biblioteca de Uso Geral para integrações com as API OmsAj |
|
|
SeliseBlocks.Genesis
Blocks Genesis |
|
|
Tisa.Infrastructure
Базовые классы и компоненты инфраструктуры приложений ТИСА. |
|
|
Simur.Core
Core platform for SIMUR |
|
|
GM.API
API Wrapper for .NET |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 9.0.0-preview.3 | 46 | 3/4/2026 |
| 8.3.0 | 18 | 3/24/2026 |
| 8.2.0 | 17 | 3/24/2026 |
| 8.2.0-preview.34 | 12 | 3/24/2026 |
| 8.2.0-preview.33 | 20 | 3/24/2026 |
| 8.2.0-preview.32 | 17 | 3/24/2026 |
| 8.2.0-preview.31 | 17 | 3/24/2026 |
| 8.2.0-preview.30 | 42 | 3/15/2026 |
| 8.2.0-preview.29 | 43 | 3/15/2026 |
| 8.2.0-preview.28 | 41 | 3/15/2026 |
| 8.2.0-preview.27 | 39 | 3/15/2026 |
| 8.2.0-preview.26 | 42 | 3/15/2026 |
| 8.2.0-preview.25 | 37 | 3/15/2026 |
| 8.2.0-preview.24 | 41 | 3/15/2026 |
| 8.2.0-preview.23 | 43 | 3/15/2026 |
| 8.2.0-preview.22 | 44 | 3/15/2026 |
| 8.2.0-preview.21 | 45 | 3/15/2026 |
| 8.2.0-preview.20 | 48 | 3/15/2026 |
| 8.1.1-preview.8 | 44 | 3/15/2026 |
| 8.1.1-preview.7 | 44 | 3/15/2026 |
- Add .NET 9 and .NET 10 support.
- Update Microsoft.AspNetCore.Http to 2.3.9, Serilog to 4.3.1 (3.1.1 for net7.0 and netstandard2.1).
- Fix: compatibility with .NET Standard 2.1 and .NET 6 (conditional compilation for ArgumentNullException.ThrowIfNull, ArgumentException.ThrowIfNullOrEmpty).
- Fix: remove dead NETFULL code from ClientIpEnricher.
- Fix: nuspec duplicate key (targetFramework casing).
- SampleWebApp: fix ASP0016 (RequestDelegate return value), use async/await.
- Tests: extended test coverage.
- Tests: migrate tests to NUnit, FluentAssertions.
- Tests: replace NSubstitute with Moq.
- Tests: suppress NU1701, nullable warnings (CS8600, CS8602, CS8603, CS8625).
- Improve README: clarify that WithClientIp uses "x-forwarded-for" header by default.
- Improve README: IWebHostEnvironment, supported frameworks, WithClientIp headerName.
- Add .editorconfig, UTF-8 BOM.