ITSS.SimpleLogs
1.5.0
dotnet add package ITSS.SimpleLogs --version 1.5.0
NuGet\Install-Package ITSS.SimpleLogs -Version 1.5.0
<PackageReference Include="ITSS.SimpleLogs" Version="1.5.0" />
<PackageVersion Include="ITSS.SimpleLogs" Version="1.5.0" />
<PackageReference Include="ITSS.SimpleLogs" />
paket add ITSS.SimpleLogs --version 1.5.0
#r "nuget: ITSS.SimpleLogs, 1.5.0"
#:package ITSS.SimpleLogs@1.5.0
#addin nuget:?package=ITSS.SimpleLogs&version=1.5.0
#tool nuget:?package=ITSS.SimpleLogs&version=1.5.0
ITSS.SimpleLogs
A lightweight, consistent logging helper for ASP.NET Core (.NET 8) applications with first-class NLog and Serilog support, ready-to-use JSON layouts/formatter, HTTP enrichment middleware, and optional request body logging.
Highlights
- NLog and Serilog: code‑first setup or configuration file based.
- JSON logs: consistent schema with
@t(timestamp),@l(level),@mt(message),@x(exception),traceId,logger, and enriched context properties. - HTTP middleware: request start/finish logging, correlation via header (e.g.,
X-Correlation-Id), duration and status. - Request body: conditional logging for POST/PUT/PATCH and only for 409/5xx responses, or always at Debug level.
- Configurable options: ability to configure request blacklist (case-insensitive prefix matching with path normalization), custom correlation header name, and field masking for sensitive data in form and body logs.
Requirements
- .NET 8 (net8.0)
Installation
dotnet add package ITSS.SimpleLogs
Current version: 1.5.0
Quick start (NLog)
1) Basic configuration in Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Enable NLog with default options
builder.Host.UseSimpleNLog();
// Code-based NLog config (targets, rules, JSON layout, rolling, etc.)
var nlog = ITSS.SimpleLogs.SimpleLogsManager.InitNLogWithDefaultConfig();
var app = builder.Build();
// HTTP enrichment middleware
app.UseNLogHttpLoggingEnrichmentMiddleware();
// (Optional) request body logging for NLog – enabled only when the RequestBody logger is active
app.UseNLogRequestPostedBodyMiddleware();
app.MapGet("/ping", () => "pong");
app.Run();
2) Configuration with options:
var builder = WebApplication.CreateBuilder(args);
// Configuration with custom options
builder.Host.UseSimpleNLog(options =>
{
options.CorrelationIdHeaderName = "X-Request-Id"; // Custom header name
options.RequestsBlackList = ["/health", "/metrics"]; // Paths excluded from logging (case-insensitive prefix matching with path normalization)
options.FormFieldsToMask = ["password", "creditCard", "ssn"]; // Form fields to mask in logs
options.BodyFieldsToMask = ["password", "creditCard", "ssn"]; // JSON body fields to mask in logs
});
var nlog = ITSS.SimpleLogs.SimpleLogsManager.InitNLogWithDefaultConfig();
var app = builder.Build();
app.UseNLogHttpLoggingEnrichmentMiddleware();
app.UseNLogRequestPostedBodyMiddleware();
app.MapGet("/ping", () => "pong");
app.Run();
3) Loading configuration from file:
// From appsettings.json
var nlog = SimpleLogsManager.InitNLogWithAppsettingsConfig();
// Or from XML file (e.g., nlog.config)
var nlog = SimpleLogsManager.InitNLogWithXmlConfig("nlog.config");
4) Minimal NLog section in appsettings.json:
{
"NLog": {
"autoReload": true,
"throwConfigExceptions": true,
"extensions": [ { "assembly": "ITSS.SimpleLogs" } ],
"targets": {
"allFile": {
"type": "File",
"fileName": "${basedir}/../Logs/WebApi.log",
"archiveEvery": "Day",
"archiveNumbering": "Rolling",
"layout": { "type": "BaseCustomJsonLayout" }
}
},
"rules": [
{ "logger": "*", "minLevel": "Info", "writeTo": "allFile" }
]
}
}
Note: The default code configuration writes a single JSON log file (../Logs/WebApi.log relative to basedir) with daily rolling; special HTTP categories (Request/Response/Correlation/RequestBody) are routed to the same file.
Note: All UseSimpleNLog and UseSimpleSerilog methods automatically clear existing logging providers before configuration to prevent conflicts. For IHostApplicationBuilder (newer pattern), use the extension methods from IHostApplicationExtenstions class instead of IHostBuilderExtensions.
Quick start (Serilog)
1) Basic configuration:
var builder = WebApplication.CreateBuilder(args);
// Enable Serilog with default options
builder.Host.UseSimpleSerilog();
// Default setup (console + file with BaseCustomJsonFormatter)
var serilog = SimpleLogsManager.InitSerilogDefaultConfig();
// Or from appsettings.json
// var serilog = SimpleLogsManager.InitSerilogWithAppsettingsConfig(builder.Configuration);
var app = builder.Build();
// HTTP enrichment middleware
app.UseSerilogHttpLoggingEnrichmentMiddleware();
app.MapGet("/ping", () => "pong");
app.Run();
2) Configuration with options:
var builder = WebApplication.CreateBuilder(args);
// Configuration with custom options
builder.Host.UseSimpleSerilog(options =>
{
options.CorrelationIdHeaderName = "X-Request-Id";
options.RequestsBlackList = ["/health", "/metrics"]; // Paths excluded from logging (case-insensitive prefix matching with path normalization)
options.FormFieldsToMask = ["password", "creditCard", "ssn"]; // Form fields to mask in logs
options.BodyFieldsToMask = ["password", "creditCard", "ssn"]; // JSON body fields to mask in logs
});
var serilog = SimpleLogsManager.InitSerilogDefaultConfig();
var app = builder.Build();
app.UseSerilogHttpLoggingEnrichmentMiddleware();
app.MapGet("/ping", () => "pong");
app.Run();
3) Example Serilog section in appsettings.json:
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"ITSS.SimpleLogs.Middlewares.SerilogHttpLoggingEnrichmentMiddleware.RequestBody": "Information"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": { "path": "Logs/log-.txt", "rollingInterval": "Day" }
}
],
"Enrich": [ "FromLogContext" ]
}
}
Request body logging controls
When is it logged:
- By default: for POST/PUT/PATCH and only for 409/5xx responses
- Always: when the
RequestBodycategory runs at Debug level
NLog:
- Category:
ITSS.SimpleLogs.Middlewares.NLogHttpLoggingEnrichmentMiddleware.RequestBody - Enable: via NLog rules (e.g., minLevel=Info) and use
HttpRequestBodyCustomJsonLayoutto emit theBodyfield - Middleware:
UseNLogRequestPostedBodyMiddleware()wiresNLog.Web.NLogRequestPostedBodyMiddlewareconditionally only when the logger is active
Serilog:
- Category:
ITSS.SimpleLogs.Middlewares.SerilogHttpLoggingEnrichmentMiddleware.RequestBody - Enable: via
MinimumLevel.Override - Operation: the middleware buffers and reads the body (
EnableBuffering)
API Quick Reference
SimpleLogsManager (NLog)
InitNLogWithDefaultConfig(Action<LoggingConfiguration>? configure = null)– code-based NLog setup (targets, rules, JSON layouts). You can mutate the config via the callback.InitNLogWithAppsettingsConfig()– registers custom layouts and loads NLog fromappsettings.json.InitNLogWithXmlConfig(string xmlFilePath)– loads NLog from XML and registers layouts.ConfigureBaseLayout(Action<BaseCustomJsonLayout> configure)– runtime JSON layout tweaks for base layout.ConfigureRequestLayout(Action<HttpRequestCustomJsonLayout> configure)– runtime JSON layout tweaks for HTTP requests.ConfigureResponseLayout(Action<HttpResponseCustomJsonLayout> configure)– runtime JSON layout tweaks for HTTP responses.ConfigureRequestBodyLayout(Action<HttpRequestBodyCustomJsonLayout> configure)– runtime JSON layout tweaks for request body.ShutdownNLog()– flushes and shuts down NLog, releasing file handles and other resources.
SimpleLogsManager (Serilog)
InitSerilogDefaultConfig()– default Serilog setup (console + file usingBaseCustomJsonFormatter).InitSerilogWithAppsettingsConfig(IConfiguration)– Serilog setup fromappsettings.json.
IHostBuilderExtensions
UseSimpleNLog(Action<SimpleLogsOptions>? options = null, Action<NLogAspNetCoreOptions>? configure = null)– configures NLog for the host with optional parameters. Automatically clears existing logging providers before configuration.UseSimpleSerilog(Action<SimpleLogsOptions>? options = null, Action<HostBuilderContext, IServiceProvider, LoggerConfiguration>? configure = null)– configures Serilog for the host with optional parameters. Automatically clears existing logging providers before configuration.
IHostApplicationExtenstions
UseSimpleNLog(Action<SimpleLogsOptions>? options = null, Action<NLogAspNetCoreOptions>? configure = null)– configures NLog for the host application builder with optional parameters. Automatically clears existing logging providers before configuration.UseSimpleSerilog(Action<SimpleLogsOptions>? options = null, Action<IHostApplicationBuilder, IServiceProvider, LoggerConfiguration>? configure = null)– configures Serilog for the host application builder. Automatically clears existing logging providers before configuration.
IApplicationBuilderExtensions
UseNLogHttpLoggingEnrichmentMiddleware()– HTTP middleware for NLog.UseSerilogHttpLoggingEnrichmentMiddleware()– HTTP middleware for Serilog.UseNLogRequestPostedBodyMiddleware()– conditional request body reader for NLog.
LoggingExtensions
LogException(this ILogger, Exception)– helper to log exceptions as Error.
SimpleLogsOptions
public class SimpleLogsOptions
{
public string[] RequestsBlackList { get; set; } = [];
public string CorrelationIdHeaderName { get; set; } = "X-Correlation-Id";
public string[] FormFieldsToMask { get; set; } = [];
public string[] BodyFieldsToMask { get; set; } = [];
}
JSON Log Format
Common fields (example):
{
"@t": "2025-01-01T12:34:56.1234567Z",
"@l": 2,
"@mt": "Request completed.",
"@x": null,
"traceId": "00-<traceId>-<spanId>-00",
"logger": "ITSS.SimpleLogs.Middlewares.SerilogHttpLoggingEnrichmentMiddleware+Response",
"StatusCode": 200,
"Duration": 123
}
Additional fields:
- For requests:
Form,QueryString,Path,Method,Env,Hostname - For request body:
Body - For responses:
StatusCode,Duration
Best Practices and Middleware Order
Recommended pipeline order:
- Global exception handling
- HTTP logging middleware (
UseNLogHttpLoggingEnrichmentMiddleware()orUseSerilogHttpLoggingEnrichmentMiddleware()) - Request body middleware (
UseNLogRequestPostedBodyMiddleware()- optional) - Routing and endpoints
Correlation configuration:
- By default, the
X-Correlation-Idheader is used - Can be changed via
SimpleLogsOptions.CorrelationIdHeaderName
Request blacklist:
- Use
SimpleLogsOptions.RequestsBlackListto exclude paths from logging. The middleware normalizes the request path by appending "/" and then checks if it starts with any path from the blacklist (case-insensitive comparison). - Important: There is a difference between
/healthand/health/in the blacklist:/healthin blacklist will match/health,/health/,/health/check,/healthcheck, and any path starting with/health(case-insensitive)/health/in blacklist will match only/health/and/health/check, but NOT/healthor/healthcheck
- Example: blacklist
["/health", "/metrics"]will exclude/health,/health/check,/healthcheck,/metrics,/metrics/prometheus, and any path starting with/healthor/metrics(case-insensitive).
Form field masking:
- Use
SimpleLogsOptions.FormFieldsToMaskto specify form field names that should be masked in logs (e.g.,password,creditCard,ssn). - Masked fields will be replaced with
"***MASKED***"in theFormfield of request logs. - Field name matching is case-insensitive.
- Example configuration:
builder.Host.UseSimpleNLog(options =>
{
options.FormFieldsToMask = ["password", "creditCard", "ssn", "token"];
});
- The masking is automatically applied when using
HttpRequestCustomJsonLayout(which is the default for request logs).
Request body field masking:
- Use
SimpleLogsOptions.BodyFieldsToMaskto specify JSON field names in request body that should be masked in logs (e.g.,password,creditCard,ssn). - Masked fields will be replaced with
"***MASKED***"in theBodyfield of request body logs. - Field name matching is case-insensitive and works recursively for nested JSON objects and arrays.
- If the request body is not valid JSON, the original body is returned without masking.
- Example configuration:
builder.Host.UseSimpleNLog(options =>
{
options.BodyFieldsToMask = ["password", "creditCard", "ssn", "token"];
});
- The masking is automatically applied when using
HttpRequestBodyCustomJsonLayout(which usesmasked-aspnet-request-bodyrenderer).
Available Layouts (NLog)
BaseCustomJsonLayout– base JSON layout for general logsHttpRequestCustomJsonLayout– layout for HTTP request logs (usesmasked-aspnet-request-formrenderer for form data)HttpResponseCustomJsonLayout– layout for HTTP response logsHttpRequestBodyCustomJsonLayout– layout for HTTP request body logs
Available Layout Renderers (NLog)
masked-aspnet-request-form– renders form data as JSON array with optional field masking. Fields to mask are specified viaSimpleLogsOptions.FormFieldsToMaskand are automatically applied when usingHttpRequestCustomJsonLayout.masked-aspnet-request-body– renders request body with optional JSON field masking. Fields to mask are specified viaSimpleLogsOptions.BodyFieldsToMaskand are automatically applied when usingHttpRequestBodyCustomJsonLayout. Works recursively for nested JSON objects and arrays.
Dependencies
NLog packages:
- NLog (6.0.3)
- NLog.Web.AspNetCore (6.0.3)
- NLog.DiagnosticSource (6.0.2)
- NLog.Targets.AtomicFile (6.0.3)
Serilog packages:
- Serilog (4.3.0)
- Serilog.AspNetCore (9.0.0)
- Serilog.Sinks.Console (6.0.0)
- Serilog.Sinks.File (7.0.0)
License
See LICENSE.txt. Usage is restricted to applications delivered by ITSS according to the relevant agreements.
Changelog
See CHANGELOG.md for the complete project change history.
| 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
- NLog (>= 6.0.3)
- NLog.DiagnosticSource (>= 6.0.2)
- NLog.Targets.AtomicFile (>= 6.0.3)
- NLog.Web.AspNetCore (>= 6.0.3)
- Serilog (>= 4.3.0)
- Serilog.AspNetCore (>= 9.0.0)
- Serilog.Sinks.Console (>= 6.0.0)
- Serilog.Sinks.File (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
See CHANGELOG.md for release notes