NeonLog.CSharp.AspNetCore
0.1.0-ci.78
dotnet add package NeonLog.CSharp.AspNetCore --version 0.1.0-ci.78
NuGet\Install-Package NeonLog.CSharp.AspNetCore -Version 0.1.0-ci.78
<PackageReference Include="NeonLog.CSharp.AspNetCore" Version="0.1.0-ci.78" />
<PackageVersion Include="NeonLog.CSharp.AspNetCore" Version="0.1.0-ci.78" />
<PackageReference Include="NeonLog.CSharp.AspNetCore" />
paket add NeonLog.CSharp.AspNetCore --version 0.1.0-ci.78
#r "nuget: NeonLog.CSharp.AspNetCore, 0.1.0-ci.78"
#:package NeonLog.CSharp.AspNetCore@0.1.0-ci.78
#addin nuget:?package=NeonLog.CSharp.AspNetCore&version=0.1.0-ci.78&prerelease
#tool nuget:?package=NeonLog.CSharp.AspNetCore&version=0.1.0-ci.78&prerelease
NeonLog.CSharp.AspNetCore
ASP.NET Core request logging middleware for neonlog-c.
Writes a structured completion log event for every HTTP request, with dynamic level selection
and automatic population of NeonLogHttpRequestContext for downstream enrichers.
Quick start
using NeonLog.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
// Register NeonLog as the logging provider
builder.Logging.AddNeonLog(builder.Configuration.GetSection("NeonLog"));
var app = builder.Build();
// Add request logging middleware (early in the pipeline)
app.UseNeonLogRequestLogging();
app.MapControllers();
app.Run();
Each request produces a log event like:
INF HTTP GET /api/orders responded 200 in 42ms
Configuration
NeonLogRequestLoggingOptions
| Member | Type | Default | Description |
|---|---|---|---|
GetLevel |
Func<HttpContext, long, Exception?, NeonLogLevel>? |
Intelligent default (see below) | Determines the log level per request |
EnrichDiagnosticContext |
Action<IDictionary<string, object?>, HttpContext>? |
null |
Add extra properties from HttpContext |
MessageTemplate |
string |
"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {ElapsedMilliseconds}ms" |
Structured message template |
Default GetLevel behaviour
When no delegate is provided, the middleware uses the same logic as the Serilog
UseSerilogRequestLogging example:
| Condition | Level |
|---|---|
| Exception thrown | Error |
| Response status code > 499 | Error |
Path is / or starts with /health |
Verbose |
| Everything else | Information |
Override with a custom delegate:
app.UseNeonLogRequestLogging(options =>
{
options.GetLevel = (httpContext, elapsedMs, ex) =>
{
if (ex != null) return NeonLogLevel.Error;
if (httpContext.Response.StatusCode > 499) return NeonLogLevel.Error;
var path = httpContext.Request?.Path.Value?.ToLowerInvariant();
if (path == "/" || (path?.StartsWith("/health") ?? false))
return NeonLogLevel.Verbose;
return httpContext.Request.Method == "GET"
? NeonLogLevel.Debug
: NeonLogLevel.Information;
};
});
Adding custom properties via EnrichDiagnosticContext
Use the EnrichDiagnosticContext callback to attach properties from HttpContext
that aren't captured automatically:
app.UseNeonLogRequestLogging(options =>
{
options.EnrichDiagnosticContext = (props, ctx) =>
{
props["CustomHeader"] = ctx.Request.Headers["X-Custom"].ToString();
};
});
Properties added here are attached to the request completion log event via
BeginScope, so they appear alongside the template parameters.
Custom message template
app.UseNeonLogRequestLogging(options =>
{
options.MessageTemplate =
"[{RequestMethod}] {RequestPath} -> {StatusCode} ({ElapsedMilliseconds}ms)";
});
How it works
- On request arrival, the middleware populates
NeonLogHttpRequestContextwith data extracted fromHttpContext(method, path, user-agent, client IP, etc.). - It calls
_next(context)and measures elapsed time withStopwatch. - After the response, it updates the ambient context with the status code and elapsed time.
- The
GetLeveldelegate determines the log level. - A structured log event is written via
ILogger<RequestLoggingMiddleware>.
Properties populated by the middleware
The middleware sets every field on NeonLogHttpRequestData from HttpContext:
| Property | Source | Example |
|---|---|---|
RequestMethod |
context.Request.Method |
"GET" |
RequestPath |
context.Request.Path |
"/api/orders" |
RequestId |
context.TraceIdentifier |
"0HMKJ0KQ3T7C7" |
CorrelationId |
context.TraceIdentifier |
"0HMKJ0KQ3T7C7" |
Host |
context.Request.Host |
"example.com:443" |
Protocol |
context.Request.Protocol |
"HTTP/1.1" |
ContentType |
context.Request.ContentType |
"application/json" |
UserAgent |
User-Agent header |
"Mozilla/5.0 …" |
ClientIp |
context.Connection.RemoteIpAddress |
"192.168.1.100" |
UrlReferrer |
Referer header |
"https://example.com/cart" |
RawUrl |
Scheme + Host + Path + QueryString | "https://example.com/api/orders?page=1" |
UriQuery |
context.Request.QueryString |
"?page=1" |
UserName |
context.User.Identity.Name or "(anonymous)" |
"alice" |
StatusCode |
Set after response via SetStatusCode() |
200 |
Elapsed |
Set after response via SetElapsed() |
42 |
Integration with the HttpRequest enricher
Because the middleware sets NeonLogHttpRequestContext, any downstream code
that logs within the same request automatically gets HTTP request properties
attached — provided the HttpRequest enricher is configured:
// In NeonLog options:
options.Enrichers.Add(NeonLogBuiltInEnricher.HttpRequest);
Each log event within the request context will receive the following properties (both neonlog-c native names and HSSerilog-compatible aliases are emitted):
| Native property | HSSerilog alias |
|---|---|
RequestMethod |
— |
RequestPath |
HttpRequestUriStem |
RequestId |
— |
CorrelationId |
CorrelationId |
Host |
— |
Protocol |
— |
ContentType |
HttpRequestContentType |
UserAgent |
HttpRequestUserAgent |
ClientIp |
HttpRequestClientHostIP |
UrlReferrer |
HttpRequestUrlReferrer |
RawUrl |
HttpRequestRawUrl |
UriQuery |
HttpRequestUriQuery |
UserName |
UserName |
StatusCode |
— |
Elapsed |
— |
RequestBody |
HttpRequestBody |
Note:
HttpRequestBodyis only populated if you add middleware that reads the request body and setsRequestBodyon the ambient context.
API
IApplicationBuilder.UseNeonLogRequestLogging()
Registers RequestLoggingMiddleware with default options. Place early in
the pipeline (after exception handling, before routing) so it captures the
full request/response cycle.
IApplicationBuilder.UseNeonLogRequestLogging(Action<NeonLogRequestLoggingOptions>)
Registers the middleware with a configuration delegate for custom level selection, enrichment, or message template.
Migrating from Serilog (HSSerilog)
If you are migrating from HSSerilog's RequestEnricher, the property names
are fully compatible. The following HSSerilog property names are emitted as
aliases alongside the native neonlog-c names:
| HSSerilog property | Source in middleware |
|---|---|
CorrelationId |
context.TraceIdentifier |
HttpRequestClientHostIP |
context.Connection.RemoteIpAddress |
HttpRequestUrlReferrer |
Referer header |
HttpRequestRawUrl |
Scheme + Host + Path + Query |
HttpRequestUserAgent |
User-Agent header |
HttpRequestUriStem |
context.Request.Path |
HttpRequestUriQuery |
context.Request.QueryString |
HttpRequestContentType |
context.Request.ContentType |
HttpRequestBody |
request.RequestBody (set externally) |
UserName |
context.User.Identity.Name or "(anonymous)" |
No changes to your log queries or dashboards are needed.
NuGet
dotnet pack bindings/dotnet/NeonLog.CSharp.AspNetCore/NeonLog.CSharp.AspNetCore.csproj -c Release
Package version follows $(NeonLogPackageVersion) (default 0.1.0).
The package has no native assets — it depends solely on the NeonLog.CSharp
package for the native neonlog-c runtime.
| 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 was computed. 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. |
-
net8.0
- NeonLog.CSharp (>= 0.1.0-ci.78)
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.1.0-ci.78 | 62 | 6/8/2026 |
| 0.1.0-ci.75 | 52 | 6/8/2026 |
| 0.1.0-ci.73 | 63 | 6/5/2026 |
| 0.1.0-ci.70 | 55 | 6/5/2026 |
| 0.1.0-ci.66 | 53 | 6/4/2026 |
| 0.1.0-ci.64 | 51 | 6/4/2026 |
| 0.1.0-ci.63 | 47 | 6/4/2026 |
| 0.1.0-ci.61 | 64 | 6/3/2026 |