ITSS.SimpleLogs 1.5.0

dotnet add package ITSS.SimpleLogs --version 1.5.0
                    
NuGet\Install-Package ITSS.SimpleLogs -Version 1.5.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="ITSS.SimpleLogs" Version="1.5.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ITSS.SimpleLogs" Version="1.5.0" />
                    
Directory.Packages.props
<PackageReference Include="ITSS.SimpleLogs" />
                    
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 ITSS.SimpleLogs --version 1.5.0
                    
#r "nuget: ITSS.SimpleLogs, 1.5.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 ITSS.SimpleLogs@1.5.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=ITSS.SimpleLogs&version=1.5.0
                    
Install as a Cake Addin
#tool nuget:?package=ITSS.SimpleLogs&version=1.5.0
                    
Install as a Cake Tool

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 RequestBody category runs at Debug level

NLog:

  • Category: ITSS.SimpleLogs.Middlewares.NLogHttpLoggingEnrichmentMiddleware.RequestBody
  • Enable: via NLog rules (e.g., minLevel=Info) and use HttpRequestBodyCustomJsonLayout to emit the Body field
  • Middleware: UseNLogRequestPostedBodyMiddleware() wires NLog.Web.NLogRequestPostedBodyMiddleware conditionally 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 from appsettings.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 using BaseCustomJsonFormatter).
  • InitSerilogWithAppsettingsConfig(IConfiguration) – Serilog setup from appsettings.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

  1. Global exception handling
  2. HTTP logging middleware (UseNLogHttpLoggingEnrichmentMiddleware() or UseSerilogHttpLoggingEnrichmentMiddleware())
  3. Request body middleware (UseNLogRequestPostedBodyMiddleware() - optional)
  4. Routing and endpoints

Correlation configuration:

  • By default, the X-Correlation-Id header is used
  • Can be changed via SimpleLogsOptions.CorrelationIdHeaderName

Request blacklist:

  • Use SimpleLogsOptions.RequestsBlackList to 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 /health and /health/ in the blacklist:
    • /health in 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 /health or /healthcheck
  • Example: blacklist ["/health", "/metrics"] will exclude /health, /health/check, /healthcheck, /metrics, /metrics/prometheus, and any path starting with /health or /metrics (case-insensitive).

Form field masking:

  • Use SimpleLogsOptions.FormFieldsToMask to specify form field names that should be masked in logs (e.g., password, creditCard, ssn).
  • Masked fields will be replaced with "***MASKED***" in the Form field 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.BodyFieldsToMask to 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 the Body field 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 uses masked-aspnet-request-body renderer).

Available Layouts (NLog)

  • BaseCustomJsonLayout – base JSON layout for general logs
  • HttpRequestCustomJsonLayout – layout for HTTP request logs (uses masked-aspnet-request-form renderer for form data)
  • HttpResponseCustomJsonLayout – layout for HTTP response logs
  • HttpRequestBodyCustomJsonLayout – 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 via SimpleLogsOptions.FormFieldsToMask and are automatically applied when using HttpRequestCustomJsonLayout.
  • masked-aspnet-request-body – renders request body with optional JSON field masking. Fields to mask are specified via SimpleLogsOptions.BodyFieldsToMask and are automatically applied when using HttpRequestBodyCustomJsonLayout. 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 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. 
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.5.0 203 11/20/2025
1.4.0 215 11/19/2025
1.3.0 219 11/14/2025
1.2.0 181 11/4/2025
1.1.0 148 10/24/2025
0.5.0 169 10/9/2025
0.4.0 174 9/11/2025

See CHANGELOG.md for release notes