Skip to content

Pragmatic.Logging

High-performance, structured logging framework for the Pragmatic.Design ecosystem. Extends .NET ILogger with zero-allocation hot paths, privacy-aware redaction, audit trail support, and multiple output providers.

Production logging needs structured output, PII redaction, correlation IDs, rate limiting, and multiple output targets — all without adding latency. The standard .NET logging infrastructure provides the ILogger foundation but leaves these concerns to the developer. String interpolation allocates on every call. Secrets leak into logs when developers forget to sanitize. Context properties require manual passing at every call site. And configuring all of these concerns together requires cobbling together multiple libraries.

// Without Pragmatic: allocates on every call, no redaction, no context
logger.LogInformation($"Order {orderId} placed by {email} via {connectionString}");
// Leaks PII (email) and secrets (connection string), allocates a string even when level is disabled

Pragmatic.Logging wraps the standard Microsoft.Extensions.Logging infrastructure with a fluent PragmaticLoggingBuilder API. One builder configures all concerns: providers, presets, privacy, performance, and context enrichment. All providers integrate with the standard ILogger<T> interface — no proprietary abstractions.

// With Pragmatic: one builder, all concerns, zero-allocation hot paths
builder.Services.AddLogging(logging =>
{
logging.ClearProviders();
var pragmatic = logging.AddPragmaticLogging();
pragmatic
.UseProductionPreset() // Background processing, rate limiting, correlation IDs
.AddConsole() // Colored terminal output
.AddFile("logs/app-{Date}.log") // Rolling file with retention
.EnableDataRedaction(r => // Automatic PII redaction
r.SensitivePropertyNames = ["password", "email", "apiKey"]);
});

Benchmarked against Serilog and NLog on .NET 10 (BenchmarkDotNet 0.14.0):

ScenarioPragmaticNLogSerilog
Simple logging21.87 ns / 64 B138.52 ns / 488 B155.06 ns / 440 B
Structured logging46.98 ns / 216 B279.84 ns / 696 B557.59 ns / 2016 B
Exception logging21.48 ns / 64 B134.99 ns / 504 B163.39 ns / 440 B
High volume (1000/iter)18.88 us / 64 KB134.75 us / 476 KB154.71 us / 430 KB

Full benchmark results are in BENCHMARK-RESULTS.md.

Terminal window
dotnet add package Pragmatic.Logging

builder.Services.AddLogging(logging =>
{
var pragmatic = logging.AddPragmaticLogging();
pragmatic
.UseDevelopmentPreset()
.AddConsole()
.AddFile("logs/app-{Date}.log");
});
// Production with rate limiting and correlation IDs
var pragmatic = logging.AddPragmaticLogging();
pragmatic
.UseProductionPreset()
.AddFile("logs/app-{Date}.log")
.AddJson(Console.OpenStandardOutput());
// GDPR-compliant logging with audit trail
var pragmatic = logging.AddPragmaticLogging();
pragmatic
.UseCompliancePreset(ComplianceStandard.Gdpr)
.EnableDataRedaction(r =>
{
r.RedactionPlaceholder = "[REDACTED]";
r.PreserveLengths = false;
})
.EnableAuditTrail(a =>
{
a.StorageType = "Database";
a.FlushIntervalSeconds = 30;
});

All providers implement IPragmaticLoggerProvider and register as ILoggerProvider with the DI container.

ProviderClassOutput
ConsolePragmaticConsoleProviderColored terminal output with structured data
FilePragmaticFileProviderFile-based with rolling, retention, async I/O
JSONPragmaticJsonProviderStructured JSON / NDJSON output
Enhanced JSONPragmaticEnhancedJsonProviderNDJSON with async buffering
MemoryPragmaticMemoryProviderIn-memory buffer for testing
DebugPragmaticDebugProviderDebug output window
NullPragmaticNullProviderNo-op for benchmarking
Windows Event LogPragmaticWindowsEventLogProviderWindows Event Log
pragmatic
.AddConsole(opts => { opts.UseColors = true; opts.IncludeStructuredData = true; })
.AddFile("logs/app-{Date}.log", opts => { opts.MaxFileSizeMB = 100; opts.RetentionDays = 30; })
.AddJson(Console.OpenStandardOutput(), opts => { opts.WriteIndented = false; })
.AddMemory()
.AddDebug()
.AddNdjsonAsync("logs/structured-{Date}.ndjson");

PragmaticFileProvider is a high-performance file logger with:

  • Channel-based async processing — lock-free queuing with System.Threading.Channels
  • Automatic file rolling — by size (configurable MaxFileSize) or time interval (Hour, Day, Week, Month, Year)
  • Retention policies — automatic cleanup of old files (MaxRetainedFiles)
  • Template-based file naming{Date}, {DateTime}, {Year}, {Month}, {Day}, {Hour} placeholders
  • Back-pressure handling — configurable Drop or Block policy when queue is full
  • Exponential backoff retry — on write failures with configurable delays
  • Health monitoringPerformCustomHealthCheck() reports Healthy/Degraded/Unhealthy
// Template-based file paths
"logs/app-{Date}.log" // app-2026-03-21.log
"logs/{Year}/{Month}/app-{Day}.log" // logs/2026/03/app-21.log
"logs/app-{Hour}.log" // app-14.log (hourly rolling)

PragmaticLoggingBuilder provides 4 built-in presets:

pragmatic.UseDevelopmentPreset();
  • MinimumLevel: Trace
  • HighPerformanceMode: disabled
  • Telemetry: disabled
  • Machine context: enabled, user context: disabled
pragmatic.UseProductionPreset();
  • MinimumLevel: Information
  • Background processing: enabled, buffer size 5000
  • Rate limiting: enabled (1000 msg/sec)
  • Correlation IDs and user context: enabled
pragmatic.UseHighPerformancePreset();
  • MinimumLevel: Information (skips Debug/Trace)
  • HighPerformanceMode: enabled
  • Zero-allocation optimizations: enabled
  • Buffer size: 10000, flush threshold: 1000
pragmatic.UseCompliancePreset(ComplianceStandard.Gdpr);
  • Redaction: enabled
  • Secret detection: enabled
  • Audit trail: enabled with database storage
  • GDPR: confidence threshold 0.8, complete redaction
  • HIPAA: confidence threshold 0.9
  • PCI-DSS: confidence threshold 0.95

The SecretDetector engine scans log content for sensitive information using pattern matching:

Detection categories:

  • Crypto (private keys) — severity Critical, confidence 0.95
  • API keys (AWS, GitHub, generic) — severity High, confidence 0.75—0.90
  • Tokens (JWT, OAuth) — severity Medium—High, confidence 0.70—0.90
  • Database (connection strings, passwords) — severity High, confidence 0.80
  • Cloud (Azure, GCP keys) — severity High, confidence 0.80

Detection features:

  • Pre-compiled regex patterns for performance
  • Property name hinting (confidence boost for password, token, key properties)
  • False positive filtering (placeholders, common GUIDs, sequential hex)
  • Overlap resolution (keeps highest-confidence match)
  • Audit trail integration

Redaction styles:

  • Placeholder[APIKEYS_REDACTED] (category-based)
  • PreserveLength************
  • PreserveStructure[JWT_HEADER].[JWT_PAYLOAD].[JWT_SIGNATURE]
  • Minimal[REDACTED]
pragmatic.EnableDataRedaction(redaction =>
{
redaction.RedactionPlaceholder = "[REDACTED]";
redaction.PreserveLengths = false;
redaction.PreserveJsonStructure = true;
redaction.SensitivePropertyNames = ["password", "secret", "apiKey"];
redaction.PropertyNamePatterns = [@".*password.*", @".*secret.*"];
redaction.MessageRedactionPatterns = [@"[\w.+-]+@[\w-]+\.[\w.]+"];
});

The audit subsystem provides compliance-grade logging for regulatory requirements.

TypePurpose
PragmaticAuditServiceCore audit service, records compliance violations
IAuditPolicyPolicy interface for audit behavior (Default, GDPR, HighPerformance, Development)
IAuditStorageStorage interface for audit entries
MemoryAuditStorageIn-memory storage (testing)
FileSystemAuditStorageFile-based audit storage
pragmatic.EnableAuditTrail(audit =>
{
audit.StorageType = "FileSystem"; // FileSystem, Database, Memory
audit.PolicyType = "GDPR"; // Default, GDPR, HighPerformance, Development
audit.BatchSize = 100;
audit.FlushIntervalSeconds = 30;
});

Lock-free, per-message rate limiting via HighPerformanceRateLimiter:

pragmatic.EnableRateLimiting(rl =>
{
rl.MaxMessagesPerSecond = 1000;
rl.BurstSize = 100;
rl.Strategy = "TokenBucket"; // TokenBucket, FixedWindow, SlidingWindow
});

ProviderProperties Added
HttpContextProviderRequestPath, RequestMethod, UserId (from claims)
CorrelationIdProviderCorrelationId
MachineContextProviderMachineName
ProcessContextProviderProcessId
ThreadContextProviderThreadId
// Middleware for automatic enrichment
app.UseMiddleware<LoggingEnrichmentMiddleware>();

For logging before DI is ready:

using var bootstrap = BootstrapLogger.Create();
bootstrap.LogInformation("Starting application...");

All options can be bound from IConfiguration:

{
"PragmaticLogging": {
"Enabled": true,
"MinimumLevel": "Information",
"HighPerformanceMode": false,
"Privacy": {
"EnableRedaction": true,
"EnableSecretDetection": true,
"ComplianceStandard": "General",
"SecretDetection": {
"MinimumSecretLength": 8,
"PrecompilePatterns": true,
"MinimumConfidenceForRedaction": 0.7
},
"DataRedaction": {
"RedactionPlaceholder": "[REDACTED]",
"SensitivePropertyNames": ["password", "secret"]
}
},
"Performance": {
"BufferSize": 1000,
"FlushThreshold": 100,
"EnableZeroAllocation": true,
"UseBackgroundProcessing": true
},
"RateLimiting": {
"Enabled": false,
"MaxMessagesPerSecond": 1000,
"Strategy": "TokenBucket"
},
"Providers": {
"Console": { "Enabled": true, "UseColors": true },
"File": { "Enabled": true, "BasePath": "./logs", "MaxFileSizeMB": 100 }
}
}
}

For hot paths, the module provides:

TypePurpose
StackAllocatedBufferStack-allocated buffer for formatting
ZeroAllocMessageFormatterMessage formatting without allocations
StringBuilderPoolObject pool for StringBuilder reuse
DefaultObjectPool<T>Generic object pool implementation
PropertyPoolPool for log property objects

TypeNamespacePurpose
PragmaticLoggingBuilderPragmatic.LoggingFluent configuration API
PragmaticLoggingOptionsPragmatic.Logging.ConfigurationMain options class
SecretDetectorPragmatic.Logging.PrivacySecret detection engine
PragmaticDataRedactorPragmatic.Logging.PrivacyData redaction service
PragmaticAuditServicePragmatic.Logging.Privacy.AuditAudit trail service
PragmaticFileProviderPragmatic.Logging.ProvidersHigh-performance file provider
PragmaticConsoleProviderPragmatic.Logging.ProvidersConsole provider
PragmaticJsonProviderPragmatic.Logging.ProvidersJSON/NDJSON provider
LoggingEnrichmentMiddlewarePragmatic.Logging.AspNetCoreASP.NET Core enrichment middleware
BootstrapLoggerPragmatic.Logging.AspNetCorePre-DI logger

| Benchmark Results | BENCHMARK-RESULTS.md |

  • Microsoft.Extensions.Logging.Abstractions 10.0.0
  • OpenTelemetry.Api (optional, for trace correlation)

Part of the Pragmatic.Design ecosystem.