PrimusSaaS.Logging 1.9.0

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

PrimusSaaS.Logging - Enterprise Logging for .NET

Package version: 1.5.0

Target Frameworks: net8.0 | net9.0 | net10.0

Enterprise-grade structured logging library for .NET applications with automatic context enrichment, PII masking, audit logging, environment-aware defaults, AWS X-Ray tracing, CloudWatch metrics, and multiple output targets.

Recommendation: For vendor-neutral metrics and distributed tracing (OpenTelemetry), use the new PrimusSaaS.Observability module. Use this package (PrimusSaaS.Logging) if you specifically require local PII masking or custom file rotation sinks.

Features

  • Structured Logging - JSON-formatted logs with rich context
  • Log Levels - DEBUG, INFO, WARNING, ERROR, CRITICAL
  • Multiple Targets - Console, File, Azure Application Insights, CloudWatch
  • PII Masking - Automatic redaction of sensitive data (regex + key-name + attribute-based)
  • [SensitiveData] Attribute - Decorate properties for automatic redaction when logged
  • File Rotation - Size-based rotation with gzip compression
  • Async Buffering - High-performance non-blocking logging
  • Custom Enrichers - Add dynamic context to every log
  • Standard ILogger - Full compatibility with Microsoft.Extensions.Logging
  • Serilog/NLog Bridge - Forward enriched logs into existing sink ecosystems
  • ASP.NET Core Integration - Middleware for automatic HTTP context enrichment
  • Audit Logging - Dedicated tamper-evident audit pipeline with typed schemas and schema versioning
  • BackgroundService Lifecycle - Structured start/stop/iteration logging for workers
  • Test Helpers - FakeAuditLogger, TestLogCapture, LogAssertions for consumer tests
  • Log Level Hot-Reload - Runtime MinLevel changes via IOptionsMonitor<LoggerOptions> (v1.4.0+)
  • PHI/Financial Masking - HIPAA (ICD-10/ICD-11) and ERISA compliance masking (v1.4.0+)
  • Environment-Aware Defaults - Auto-configures Development/Staging/Production settings (v1.5.0+)
  • AWS X-Ray Integration - Segment helpers, fault recording, X-Ray/W3C trace ID conversion (v1.5.0+)
  • CloudWatch Metrics - Embedded Metric Format (EMF) bridge for System.Diagnostics.Metrics (v1.5.0+)
  • Routing Telemetry - Typed models for orchestrator routing and dispatch decisions (v1.5.0+)
  • SourceLink + Deterministic Builds - Step into SDK source during debugging (v1.5.0+)

Installation

dotnet add package PrimusSaaS.Logging --version 1.5.0

For CloudWatch integration:

dotnet add package PrimusSaaS.Logging.CloudWatch --version 1.5.0

Quick Start

Register Services

using PrimusSaaS.Logging.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.ClearProviders();
builder.Logging.AddPrimus(builder.Configuration.GetSection("PrimusLogging"));

var app = builder.Build();

app.UsePrimusLogging();

app.Run();

[SensitiveData] Attribute

Decorate model properties with [SensitiveData] to automatically redact them when logged in context dictionaries. No need to register key names manually.

using PrimusSaaS.Logging.Core;

public class UserProfile
{
    public string Name { get; set; }

    [SensitiveData]
    public string Email { get; set; }

    [SensitiveData("Financial")]
    public string TaxId { get; set; }
}

// When logged:
logger.Info("Profile loaded", new Dictionary<string, object?>
{
    ["user"] = profile  // Email and TaxId are automatically redacted
});

Attribute-based redaction is enabled by default. Disable via PiiOptions.EnableAttributeBasedRedaction = false.


Typed Audit Entries

Use the AuditEntries factory for structured, category-specific audit events:

using PrimusSaaS.Logging.Audit;

// Data access audit
auditLogger.Log(AuditEntries.DataAccess("user-1", "Read", "Orders:123", durationMs: 45.2));

// Security audit
auditLogger.Log(AuditEntries.Security("user-1", "Login", AuditOutcome.Failure,
    ipAddress: "10.0.0.1", reason: "Invalid password"));

// Governance audit (AI/compliance decisions)
auditLogger.Log(AuditEntries.Governance("system", "PolicyEvaluation", "GDPR-Consent",
    confidenceScore: 0.95, reasoning: "User consent verified"));

// Configuration change audit
auditLogger.Log(AuditEntries.ConfigurationChange("admin-1", "MaxRetries",
    oldValue: "3", newValue: "5"));

// Lifecycle audit
auditLogger.Log(AuditEntries.Lifecycle("user-1", "Deleted", "Order", "ORD-123"));

Available categories: DataAccess, Security, Governance, ConfigurationChange, Lifecycle.


CloudWatch Audit Routing

Route audit entries to a separate CloudWatch log group:

using PrimusSaaS.Logging.CloudWatch;

builder.Logging.AddPrimus(options =>
{
    options.ApplicationId = "my-app";

    // Operational logs go to one log group
    options.AddCloudWatchTarget(cw =>
    {
        cw.LogGroupName = "/app/my-app/logs";
        cw.Region = "us-east-1";
    });

    // Audit entries go to a separate log group
    options.AddCloudWatchAuditTarget(cw =>
    {
        cw.LogGroupName = "/app/my-app/audit";
        cw.Region = "us-east-1";
    });
});

BackgroundService Lifecycle Logging

Extend PrimusBackgroundService to get automatic structured logging for worker services:

using PrimusSaaS.Logging.Extensions;
using PrimusSaaS.Logging.Core;

public class OrderSyncWorker : PrimusBackgroundService
{
    public OrderSyncWorker(Logger logger) : base(logger, "OrderSyncWorker") { }

    protected override TimeSpan IterationDelay => TimeSpan.FromMinutes(5);

    protected override async Task ExecuteIterationAsync(CancellationToken ct)
    {
        // Your worker logic here - lifecycle is logged automatically:
        // Starting, IterationCompleted (with duration), IterationFailed, Stopped
        await SyncOrdersAsync(ct);
    }

    protected override Task<bool> OnIterationErrorAsync(
        Exception ex, long iterationCount, CancellationToken ct)
    {
        // Return false to stop the service on error, true to continue (default: true)
        return Task.FromResult(iterationCount < 10);
    }
}

Test Helpers

Ship with the NuGet package for consumer test convenience:

using PrimusSaaS.Logging.Testing;
using PrimusSaaS.Logging.Audit;

// FakeAuditLogger - captures audit entries in-memory
var fakeAudit = new FakeAuditLogger();
// ... inject into code under test ...
Assert.True(fakeAudit.HasEvent("UserLogin"));
Assert.Equal(2, fakeAudit.GetEvents("UserLogin").Count);

// TestLogCapture - captures log entries
var capture = new TestLogCapture();
var logger = new Logger(new LoggerOptions
{
    ApplicationId = "test-app",
    CustomTargets = new List<ITarget> { capture }
});
logger.Info("Hello");
Assert.True(capture.HasMessage("Hello"));

// LogAssertions - fluent assertion helpers
LogAssertions.AssertLogContains(capture, "Hello");
LogAssertions.AssertLogDoesNotContain(capture, "secret");
LogAssertions.AssertNoPii(capture);  // Smoke test for unmasked emails/SSNs
LogAssertions.AssertAuditRecorded(fakeAudit, "UserLogin");
LogAssertions.AssertAuditRecorded(fakeAudit, "UserLogin", AuditOutcome.Success);
LogAssertions.AssertAuditCount(fakeAudit, 3);

Environment-Aware Defaults (v1.5.0+)

Pass IHostEnvironment to automatically apply environment-specific defaults:

using PrimusSaaS.Logging.Extensions;

builder.Services.AddPrimusLogging(builder.Environment);
Setting Development Staging Production
MinLevel Debug Info Warning
Console Pretty true - false (JSON)
PII Masking Opt-in Strict (all on) Strict + MaskIPs
Sampling Disabled Enabled Enabled

AWS X-Ray Integration (v1.5.0+)

Start properly annotated Activities that appear as segments in AWS X-Ray:

using PrimusSaaS.Logging.Tracing;

// Start an X-Ray segment with tenant context
using var activity = XRayIntegration.StartXRaySegment("ProcessOrder", tenantId: "tenant-42");
try
{
    await ProcessOrderAsync();
}
catch (Exception ex)
{
    XRayIntegration.RecordFault(activity, ex);
    throw;
}

Convert between X-Ray and W3C trace ID formats:

// X-Ray → W3C
var w3cId = XRayIntegration.ConvertXRayToW3CTraceId("1-5759e988-bd862e3fe1be46a994272793");

// W3C → X-Ray
var xrayId = XRayIntegration.ConvertW3CToXRayTraceId("5759e988bd862e3fe1be46a994272793");

CloudWatch Metrics (v1.5.0+)

Bridge System.Diagnostics.Metrics to CloudWatch via Embedded Metric Format (EMF):

using PrimusSaaS.Logging.CloudWatch;

var publisher = CloudWatchExtensions.CreateMetricsPublisher(options =>
{
    options.MetricsLogGroupName = "/app/my-app/metrics";
    options.MetricsNamespace = "MyApp/Primus";
    options.FlushIntervalMs = 60_000;  // 1 minute
});

// Metrics are automatically collected from PrimusActivitySource:
// - primus.requests_processed (Counter)
// - primus.errors_logged (Counter)
// - primus.request_duration (Histogram)

Routing Telemetry (v1.5.0+)

Typed models for orchestrator routing and dispatch telemetry:

using PrimusSaaS.Logging.Telemetry;

// Routing decision telemetry
var routing = new RoutingTelemetryRecord("trace-123", "tenant-42", "evt-001", "Routed")
{
    Reason = "Matched claims domain",
    CompletedAt = DateTime.UtcNow
};
auditLogger.LogRoutingTelemetry(routing);

// Dispatch telemetry with confidence scores
var dispatch = new RoutingDispatchTelemetry(
    "trace-123", "agent-benefits", "tenant-42",
    new[] { "Claims", "Benefits" },
    new Dictionary<string, double> { ["Claims"] = 0.95, ["Benefits"] = 0.87 })
{
    Status = "Completed",
    DurationMs = 142.5
};
auditLogger.LogDispatchTelemetry(dispatch);

Performance

  • Async Buffering: Non-blocking writes with configurable buffer size.
  • Thread-Safe: Lock-free reads, minimal contention.
  • Attribute Cache: [SensitiveData] reflection results are cached per-type for zero-allocation lookups after first use.
  • Compression: Gzip reduces storage by ~70%.
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 is compatible.  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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on PrimusSaaS.Logging:

Package Downloads
PrimusSaaS.Logging.CloudWatch

AWS CloudWatch Logs target for PrimusSaaS.Logging. Enables structured log delivery to CloudWatch with automatic log group/stream management and batched writes.

PrimusSaaS.Logging.GrafanaLoki

Grafana Loki push target for PrimusSaaS.Logging. Delivers structured, PII-masked log entries to Loki via the HTTP push API with label-based streaming, batching and retry support.

PrimusSaaS.Logging.Splunk

Splunk HTTP Event Collector (HEC) target for PrimusSaaS.Logging. Delivers structured, PII-masked log entries to Splunk via HEC with batching and retry support.

PrimusSaaS.Logging.GcpCloudLogging

Google Cloud Logging target for PrimusSaaS.Logging. Delivers structured, PII-masked log entries to GCP Cloud Logging via the REST API v2 with batching and retry support. Supports service-account JSON credentials or Application Default Credentials.

PrimusSaaS.Logging.Datadog

Datadog Logs Intake target for PrimusSaaS.Logging. Delivers structured, PII-masked log entries to Datadog via the HTTP Logs Intake API with batching and retry support.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.9.0 97 5/17/2026
1.7.2 216 5/1/2026
1.7.0 132 4/19/2026
1.6.0 350 4/19/2026
1.2.6 141 2/26/2026
1.2.5 117 2/25/2026
1.2.4 1,115 11/30/2025
1.2.3 455 11/30/2025
1.2.2 282 11/28/2025
1.2.1 230 11/24/2025
1.1.1 223 11/24/2025
1.1.0 225 11/24/2025
1.0.0 214 11/24/2025

v1.9.0 — NEW: ClaimsTenantIdAccessor + ClaimsUserIdAccessor built-in implementations. UseClaimsTenantId() and UseClaimsUserId() convenience extensions on IServiceCollection. Startup warnings now include exact copy-paste fix using these built-in classes.

v1.8.0 — NEW: PrimusLoggingStartupValidator hosted service — warns at startup when ITenantIdAccessor or IUserIdAccessor are not registered in DI. CloudWatch: AddCloudWatchTarget() auto-applies XRayTraceIdFormat when region is configured; CloudWatchMetricsPublisher logs first PutMetricData failure with exact IAM action needed.

v1.7.2 — NEW: AwsXRayTraceHeader helper in PrimusSaaS.Logging.Tracing for producing/parsing the AWS X-Ray "AWSTraceHeader" wire format (Root=...;Parent=...;Sampled=...). Lets SQS/SNS/Lambda publishers stitch traces into the X-Ray service map without taking an AWSSDK or OpenTelemetry dependency in the core package. Includes Format(traceId), FromActivity(Activity), and TryParse(header, ...) with full round-trip tests.

v1.7.1 — Maintenance: documentation and packaging updates.

v1.7.0 — W3C traceparent propagation in LoggingMiddleware: inbound traceparent/tracestate headers are now parsed and restored into .NET Activity infrastructure, enabling full distributed trace stitching across services in CloudWatch, X-Ray, and Jaeger.

v1.6.0 — Pluggable PII strategy interface (IPiiStrategy) for custom masking/tokenization;

v1.5.0:
- NEW: Environment-aware defaults — AddPrimusLogging(IHostEnvironment) auto-configures for Development/Staging/Production.
- NEW: RoutingTelemetryRecord and RoutingDispatchTelemetry typed schema models matching orchestrator contract schemas.
- NEW: TelemetryLoggerExtensions — LogRoutingTelemetry() and LogDispatchTelemetry() for audit-logged telemetry.
- NEW: XRayIntegration helper — StartXRaySegment(), RecordFault(), X-Ray↔W3C trace ID conversion, ADOT bridge documentation.
- NEW: CloudWatchMetricsPublisher — bridges System.Diagnostics.Metrics to CloudWatch via Embedded Metric Format (EMF).
- NEW: Additional PrimusActivitySource metrics — requests_processed, errors_logged, request_duration counters/histograms.
- NEW: SourceLink + deterministic builds for both PrimusSaaS.Logging and PrimusSaaS.Logging.CloudWatch.
- NEW: XML documentation file generation enabled in NuGet packages.
- INFRA: CloudWatch package version aligned to 1.5.0.
- TESTS: 45 new production completion tests — 186/186 passing.

v1.4.0:
- NEW: Log level hot-reload via IOptionsMonitor — change MinLevel at runtime without restart.
- NEW: WardenAuditRecord typed model + LogWardenValidation() extension for AI governance compliance.
- NEW: AcpEnvelopeAuditRecord typed model + LogAcpEnvelope() extension for agent communication traceability.
- NEW: AuditEntry.SchemaVersion field ("1.0") for compliance audit schema evolution.
- NEW: PHI diagnosis code masking (MaskDiagnosisCodes, default: true) — ICD-10/ICD-11 patterns.
- NEW: Financial account masking (MaskFinancialAccounts, default: false) — ERISA compliance.
- NEW: CloudWatch 256KB entry size guard with automatic truncation.
- NEW: ILogger<T> extensions for LogQueryPerformance() and BeginEventScope().
- TESTS: 21 new production compliance tests — 141/141 passing.

v1.3.0:
- NEW: [SensitiveData] attribute for automatic property-level PII redaction on logged objects.
- NEW: Typed audit entries via AuditEntries factory (DataAccess, Security, Governance, ConfigurationChange, Lifecycle).
- NEW: CloudWatch audit routing — AddCloudWatchAuditTarget() for separate audit log groups.
- NEW: PrimusBackgroundService base class for structured worker lifecycle logging.
- NEW: Consumer test helpers — FakeAuditLogger, TestLogCapture, LogAssertions shipped in NuGet.
- NEW: AuditTargetOptions.CustomTargets for injecting custom audit targets (e.g., CloudWatch).
- NEW: PiiOptions.EnableAttributeBasedRedaction toggle (default: true).
- TESTS: 25 new tests covering all gap closure features — 120/120 passing.

v1.2.6:
- SECURITY: Added phone number masking (MaskPhones, default: true).
- SECURITY: Added IP address masking (MaskIPs, default: false — opt in for GDPR).
- SECURITY: Pinned System.Drawing.Common 8.0.0+ to eliminate NU1904 CVE warning.
- FIX: LogAuditAsync() extension now works on ILogger<T> and ILogger (not just internal Logger type).
- FIX: LogAuditExtensions namespace changed to PrimusSaaS.Logging.Extensions — matches the using statement in all docs.
- DOCS: Console guide updated — documented dual-output format for Pretty:true.
- DOCS: All version references updated to 1.2.6 across all doc pages.
- DOCS: Fixed TargetOptions → TargetConfig in troubleshooting.md code sample.
- TESTS: 6 new unit tests for phone/IP masking — 45/45 passing.

v1.2.5:
- DOCS: Fixed missing DI registration example in console guide (OrderService not wired).
- DOCS: Fixed sampling config — added appsettings.json approach alongside code approach.
- DOCS: Fixed enrichers section — clarified both using statements required.
- DOCS: Removed duplicate Next Steps section in overview.

v1.2.4:
- E2E tested: All endpoint tests passing with structured logging, correlation IDs, and PII masking.
- Verified API accuracy: UsePrimusLogging, LogLevel integration, async buffering.
- Production-ready with comprehensive copy-paste code samples.

v1.2.3:
- DOCS: Comprehensive documentation update with accurate implementation examples and best practices.
- Improved developer experience with clear migration guides and copy-paste ready samples.

v1.2.2: Resolved duplicate UsePrimusLogging extension ambiguity; safe serialization; scopes + correlation IDs; async buffering with metrics.