LowCodeHub.Logging
0.0.11
dotnet add package LowCodeHub.Logging --version 0.0.11
NuGet\Install-Package LowCodeHub.Logging -Version 0.0.11
<PackageReference Include="LowCodeHub.Logging" Version="0.0.11" />
<PackageVersion Include="LowCodeHub.Logging" Version="0.0.11" />
<PackageReference Include="LowCodeHub.Logging" />
paket add LowCodeHub.Logging --version 0.0.11
#r "nuget: LowCodeHub.Logging, 0.0.11"
#:package LowCodeHub.Logging@0.0.11
#addin nuget:?package=LowCodeHub.Logging&version=0.0.11
#tool nuget:?package=LowCodeHub.Logging&version=0.0.11
LowCodeHub.Logging
A production-oriented logging library for ASP.NET Core built on Serilog. One extension method configures structured logging, HTTP request enrichment, sensitive data masking, file/console sinks, forwarded headers, and self-diagnostics — with safe defaults and PII-conscious enrichment.
Why This Library?
| Feature | LowCodeHub.Logging | Raw Serilog Setup | Default ASP.NET Logging |
|---|---|---|---|
| Setup | One extension method | 50+ lines of config | Built-in but limited |
| HTTP enrichment | PII-conscious defaults | Manual middleware | Request logging only |
| Exception destructuring | Pluggable — bring official Serilog.Exceptions.* destructurers | Manual | Stack trace only |
| Sensitive data masking | Configurable operators + allowlisted query keys | Manual | None |
| File sink | Pre-configured rolling + retention | Manual setup | None |
| Forwarded headers | Integrated proxy config | Separate middleware | Separate middleware |
| Self-diagnostics | Built-in Serilog SelfLog | Manual | None |
| Startup validation | Fail-fast on invalid config | Silent failures | Silent failures |
Installation
dotnet add package LowCodeHub.Logging
Quick Start
using LowCodeHub.Logging.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.AddEnhancedSerilogLogging(); // binds the "LoggingOptions" section
var app = builder.Build();
app.UseHttpContextEnricher(); // uses the RequestEnrichment options bound above
app.MapGet("/", () => "ok");
app.Run();
That's it. Your application now has structured console + file logging, HTTP request enrichment (with PII-safe defaults), and sensitive data masking — all from two lines of setup.
Table of Contents
- Configuration
- Exception Destructuring
- HTTP Context Enrichment
- How It Works
- Best Practices
- Requirements
- License
Configuration
Full Configuration Example
{
"LoggingOptions": {
"ServiceName": "orders-api",
"MinimumLogLevel": "Information",
"LevelOverrides": {
"Microsoft": "Warning",
"System": "Warning"
},
"ExcludedRequestPaths": ["/health"],
"WriteToFile": true,
"ConsoleLogging": {
"UseCompactJson": true,
"Theme": "literate"
},
"FileLogging": {
"LogDirectory": "Logs",
"LogFileName": "app.log",
"RollingInterval": "Day",
"RetainedFileCountLimit": 14,
"SharedFile": true
},
"ExceptionHandling": {
"MaxDestructuringDepth": 3
},
"RequestEnrichment": {
"IncludeQueryString": false,
"IncludeAuthenticatedUser": false,
"IncludeUserRoles": false,
"IncludeUserAgent": true,
"IncludeReferer": false,
"AllowedQueryKeys": ["page", "pageSize"]
},
"SensitiveDataMasking": {
"Enabled": true,
"MaskValue": "***MASKED***",
"MaskEmailAddresses": true,
"MaskIbanNumbers": true,
"MaskCreditCardNumbers": false,
"MaskProperties": ["Password", "Token"],
"ExcludeProperties": []
},
"ForwardedHeaders": {
"Enabled": true,
"ForwardLimit": 1,
"RequireHeaderSymmetry": true,
"KnownProxies": ["10.0.0.10"],
"KnownNetworks": ["10.244.0.0/16"]
},
"SelfLog": {
"Enabled": true,
"WriteToConsoleError": true,
"FilePath": "Logs/serilog-selflog.txt"
}
}
}
Logging Options
| Option | Default | Description |
|---|---|---|
ServiceName |
required | Service name added to every log entry |
MinimumLogLevel |
Information |
Minimum log level (Verbose, Debug, Information, Warning, Error, Fatal) |
LevelOverrides |
Microsoft, Microsoft.EntityFrameworkCore, System → Warning |
Per-namespace minimum level overrides. Configuration values merge on top of the defaults — to re-enable a namespace, set its value to a lower level |
ExcludedRequestPaths |
["/health"] |
Request path prefixes whose log events are dropped. Segment-based: /health matches /health and /health/ready but not /healthcare |
WriteToFile |
false |
Enable file sink |
Console Logging
| Option | Default | Description |
|---|---|---|
UseCompactJson |
true |
Use compact JSON format (recommended for containers) |
OutputTemplate |
timestamp/level/source template | Custom output template (when not using compact JSON) |
Theme |
"literate" |
Console theme: code, literate, grayscale, sixteen, colored, none |
File Logging
Log files are written under the application content root (not the process working directory).
| Option | Default | Description |
|---|---|---|
LogDirectory |
"Logs" |
Directory for log files, relative to the content root |
LogFileName |
"log.txt" |
Log file name |
RollingInterval |
Day |
Rolling interval (Infinite, Year, Month, Day, Hour, Minute) |
RetainedFileCountLimit |
15 |
Number of log files to retain |
SharedFile |
true |
Allow shared file access (for multi-process scenarios) |
OutputTemplate |
timestamp/level/source template | Custom output template |
Request Enrichment
| Option | Default | Description |
|---|---|---|
IncludeQueryString |
false |
Log query string values |
IncludeAuthenticatedUser |
false |
Log authenticated user identity |
IncludeUserRoles |
false |
Log user role claims |
IncludeUserAgent |
true |
Log User-Agent header |
IncludeReferer |
false |
Log Referer header |
AllowedQueryKeys |
[] |
Allowlist for query string keys (only logged when IncludeQueryString is true) |
Sensitive Data Masking
Masking runs globally over rendered log messages and properties via Serilog.Enrichers.Sensitive.
| Option | Default | Description |
|---|---|---|
Enabled |
true |
Enable sensitive data masking |
MaskValue |
"***MASKED***" |
Replacement text for masked values |
MaskEmailAddresses |
true |
Mask values matching email addresses |
MaskIbanNumbers |
true |
Mask values matching IBAN numbers |
MaskCreditCardNumbers |
false |
Mask values matching credit card numbers |
MaskProperties |
[] |
Property names that are always masked |
ExcludeProperties |
[] |
Property names that are never masked |
Forwarded Headers
Invalid KnownProxies / KnownNetworks entries fail at startup, not at first request.
| Option | Default | Description |
|---|---|---|
Enabled |
true |
Enable X-Forwarded-For / X-Forwarded-Proto handling |
ForwardLimit |
1 |
Max hops to process |
RequireHeaderSymmetry |
true |
Require header count symmetry |
KnownProxies |
[] |
Trusted proxy IP addresses |
KnownNetworks |
[] |
Trusted proxy networks (CIDR notation) |
Self-Diagnostics
Serilog's SelfLog is process-global: the first host to configure it wins, and later configurations in the same process are no-ops.
| Option | Default | Description |
|---|---|---|
Enabled |
false |
Enable Serilog SelfLog for diagnosing sink/serialization failures |
WriteToConsoleError |
true |
Write SelfLog to stderr |
FilePath |
null |
Optional file path for SelfLog output |
Exception Destructuring
Serilog.Exceptions' default destructurers are always registered. For richer destructuring of third-party exception types, pass destructurers from the official satellite packages — they are no longer bundled, so this library does not force EF Core, SqlClient, or Refit onto your dependency graph:
dotnet add package Serilog.Exceptions.Refit # Refit ApiException
dotnet add package Serilog.Exceptions.EntityFrameworkCore # EF Core DbUpdateException
dotnet add package Serilog.Exceptions.SqlServer # Microsoft.Data.SqlClient SqlException
builder.AddEnhancedSerilogLogging(
"LoggingOptions",
new ApiExceptionDestructurer(),
new DbUpdateExceptionDestructurer(),
new SqlExceptionDestructurer());
HTTP Context Enrichment
app.UseHttpContextEnricher(); // register early in the middleware pipeline
The enricher adds contextual properties to every request-completion log entry. It automatically uses the RequestEnrichment options bound by AddEnhancedSerilogLogging; pass an options instance explicitly to override.
- Always: Request method, path, status code, protocol, host, scheme, trace identifier, client IP
- Opt-in: Query string (allowlisted keys only), authenticated user, user roles, User-Agent, Referer
Events for paths in ExcludedRequestPaths (default /health) are excluded.
How It Works
┌─────────────────────────────────────────────────────────┐
│ AddEnhancedSerilogLogging(loggingSection, ...) │
└─────────────────────┬───────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────────┐ ┌──────────────────┐
│ Serilog │ │ Enrichers │ │ Destructurers │
│ Sinks │ │ │ │ │
├──────────┤ ├──────────────┤ ├──────────────────┤
│Console │ │Service Name │ │Serilog.Exceptions│
│(compact │ │Correlation Id│ │defaults │
│ JSON) │ │HTTP Context │ │ │
│ │ │Machine Name │ │+ any you pass in │
│File │ │Process Id/ │ │(Refit, EF Core, │
│(rolling) │ │ Name │ │ SqlClient, ...) │
│ │ │Sensitive Data│ │ │
│Debug │ │ Masking │ │ │
└──────────┘ └──────────────┘ └──────────────────┘
- Configuration validation — Options (including proxy IPs/CIDRs) are validated at startup. Invalid configuration fails fast.
- Serilog bootstrap — Console + Debug sinks are configured first for startup logging.
- Host integration —
UseSerilog()replaces the default logger with the configured Serilog pipeline. - Request logging — Serilog's
UseSerilogRequestLogging()adds HTTP request logging middleware. - HTTP enrichment —
UseHttpContextEnricher()adds contextual properties per request.
Best Practices
- Set a real
ServiceNameper service. - Keep
IncludeQueryString=falseunless you truly need it. - If query logging is enabled, use
AllowedQueryKeysallowlist only. - Keep user identity fields disabled by default in public-facing APIs.
- Configure
KnownProxies/KnownNetworksin Kubernetes or behind ingress. - Enable
SelfLogin production to catch sink/serialization failures. - Use compact JSON logs in containerized environments.
- Keep file retention bounded to avoid disk exhaustion.
- Add
MaskPropertiesentries for any domain-specific secrets (tokens, national IDs).
Requirements
- .NET 10 or later
Serilog.AspNetCore10.0+ (included as a dependency)
License
MIT © Ahmed Abuelnour
| Product | Versions 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. |
-
net10.0
- Serilog.AspNetCore (>= 10.0.0)
- Serilog.Enrichers.CorrelationId (>= 3.0.1)
- Serilog.Enrichers.Environment (>= 3.0.1)
- Serilog.Enrichers.Process (>= 3.0.0)
- Serilog.Enrichers.Sensitive (>= 2.1.0)
- Serilog.Exceptions (>= 8.4.0)
- Serilog.Formatting.Compact (>= 3.0.0)
- Serilog.Sinks.Async (>= 2.1.0)
- Serilog.Sinks.Console (>= 6.1.1)
- 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.