LayeredCraft.StructuredLogging 1.0.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package LayeredCraft.StructuredLogging --version 1.0.0.3
                    
NuGet\Install-Package LayeredCraft.StructuredLogging -Version 1.0.0.3
                    
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="LayeredCraft.StructuredLogging" Version="1.0.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LayeredCraft.StructuredLogging" Version="1.0.0.3" />
                    
Directory.Packages.props
<PackageReference Include="LayeredCraft.StructuredLogging" />
                    
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 LayeredCraft.StructuredLogging --version 1.0.0.3
                    
#r "nuget: LayeredCraft.StructuredLogging, 1.0.0.3"
                    
#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.
#addin nuget:?package=LayeredCraft.StructuredLogging&version=1.0.0.3
                    
Install as a Cake Addin
#tool nuget:?package=LayeredCraft.StructuredLogging&version=1.0.0.3
                    
Install as a Cake Tool

LayeredCraft.StructuredLogging

Build Status NuGet Downloads

Simplified, structured logging for modern .NET apps — overloads, conditionals, and performance built-in.

Features

  • 🚀 High Performance - Built-in level checks and efficient parameter handling
  • 📊 Structured Logging - Rich contextual data with strongly-typed parameters
  • 🔧 Easy Integration - Drop-in replacement for standard ILogger calls
  • 🎯 Scope Management - Comprehensive scope tracking with automatic disposal
  • Performance Monitoring - Built-in timing and performance tracking
  • 🧪 Testing Support - Complete testing framework with assertions and mocking
  • 📦 Multi-Target - Supports .NET 8.0, .NET 9.0, and .NET Standard 2.1

Installation

dotnet add package LayeredCraft.StructuredLogging

Quick Start

using LayeredCraft.StructuredLogging;
using Microsoft.Extensions.Logging;

// Basic logging
logger.Information("User logged in successfully");
logger.Warning("Rate limit exceeded for user {UserId}", userId);
logger.Error(exception, "Failed to process order {OrderId}", orderId);

// Structured logging with multiple parameters
logger.Information("Order processed for user {UserId} with total {Total:C}", 
    userId, orderTotal);

// Performance monitoring
using (logger.TimeOperation("Database operation"))
{
    // Your database code here
} // Automatically logs execution time

// Enriched logging with context
logger.LogWithContext(LogLevel.Information, "Starting order processing", "UserId", userId);
logger.InformationWithUserId(userId, "Order processing started");

Core Extensions

Log Level Extensions

All standard log levels are supported with convenient extension methods:

// Debug logging
logger.Debug("Debug information");
logger.Debug("Processing item {ItemId}", itemId);

// Verbose/Trace logging
logger.Verbose("Detailed trace information");
logger.Verbose("Entering method {MethodName}", methodName);

// Information logging
logger.Information("Operation completed successfully");
logger.Information("User {UserId} performed action {Action}", userId, action);

// Warning logging
logger.Warning("Performance threshold exceeded");
logger.Warning("Retry attempt {AttemptNumber} for operation {OperationId}", 
    attemptNumber, operationId);

// Error logging
logger.Error("Operation failed");
logger.Error(exception, "Failed to save entity {EntityId}", entityId);

// Critical logging
logger.Critical("System is in critical state");
logger.Critical(exception, "Database connection lost");

Scope Management

Create logging scopes for better context tracking:

// Simple scopes
using (logger.BeginScope("UserRegistration"))
{
    logger.Information("Starting user registration");
    // Registration logic
}

// Structured scopes with properties
using (logger.BeginScope("OrderId", orderId))
{
    logger.Information("Processing order");
    // Order processing logic
}

// Complex scopes with multiple properties
using (logger.BeginScopeWith(new { UserId = userId, SessionId = sessionId }))
{
    logger.Information("User session started");
    // Session logic
}

// Timed scopes for performance monitoring
using (logger.TimeOperation("DatabaseQuery"))
{
    // Database operation
} // Automatically logs execution time

Enrichment

Add contextual information to log entries:

// Context-specific logging methods
logger.LogWithUserId(LogLevel.Information, userId, "User operation completed");
logger.LogWithRequestId(LogLevel.Information, requestId, "Request processed");
logger.LogWithCorrelationId(LogLevel.Information, correlationId, "Service call completed");

// Convenience methods for common log levels
logger.InformationWithUserId(userId, "User profile updated");
logger.WarningWithRequestId(requestId, "Request took longer than expected");
logger.ErrorWithCorrelationId(correlationId, "Service call failed", exception);

// Custom context enrichment
logger.LogWithContext(LogLevel.Information, "Operation completed", "Duration", duration);
logger.LogWithContext(LogLevel.Warning, "Rate limit approaching", "UserId", userId);

// Automatic caller information
logger.LogWithCaller(LogLevel.Debug, "Method execution completed");
logger.InformationWithCaller("Operation finished successfully");

Performance Monitoring

Built-in performance tracking capabilities:

// Timed operations
using (logger.TimeOperation("DatabaseQuery"))
{
    // Your database code
} // Logs: "DatabaseQuery completed in 150ms"

// Synchronous timed operations
var result = logger.Time("CalculateSum", () =>
{
    return numbers.Sum();
});

// Asynchronous timed operations
await logger.TimeAsync("FetchUserData", async () =>
{
    await userService.GetUserAsync(userId);
});

// Method-level timing with caller info
using (logger.TimeMethod())
{
    // Current method is automatically timed
}

Testing Support

Comprehensive testing framework for verifying logging behavior:

[Test]
public void Should_Log_User_Registration()
{
    // Arrange
    var testLogger = new TestLogger();
    var userService = new UserService(testLogger);

    // Act
    userService.RegisterUser("john@example.com");

    // Assert
    testLogger.Should().HaveLoggedInformation()
        .WithMessage("User registered successfully")
        .WithProperty("Email", "john@example.com");

    // Alternative assertion syntax
    testLogger.AssertLogEntry(LogLevel.Information, "User registered");
    testLogger.AssertLogCount(1);
    testLogger.Should().HaveExactly(1).LogEntries();
}

[Test]
public void Should_Handle_Registration_Errors()
{
    // Arrange
    var testLogger = new TestLogger();
    var userService = new UserService(testLogger);

    // Act & Assert
    Assert.Throws<ValidationException>(() => 
        userService.RegisterUser("invalid-email"));

    testLogger.Should().HaveLoggedError()
        .WithException<ValidationException>()
        .WithMessage("Invalid email format");
}

TestLogger Features

// Get specific log entries
var lastEntry = testLogger.GetLastLogEntry();
var errorEntries = testLogger.GetLogEntries(LogLevel.Error);
var entriesWithException = testLogger.GetLogEntriesWithException<ArgumentException>();

// Search log entries
var userEntries = testLogger.GetLogEntriesContaining("user");
var hasError = testLogger.HasLogEntry(LogLevel.Error, "failed");

// Assertions
testLogger.AssertLogCount(5);
testLogger.AssertLogEntry(LogLevel.Information, "expected message");
testLogger.AssertNoLogEntries(LogLevel.Error);

// Clear logs between tests
testLogger.Clear();

Advanced Usage

Conditional Logging

All logging methods include built-in level checks for optimal performance:

// These methods automatically check if the level is enabled
logger.Debug("Expensive debug info: {Data}", ExpensiveOperation());
// ExpensiveOperation() only called if Debug level is enabled

Exception Handling

Robust exception logging with context:

try
{
    // Risky operation
}
catch (Exception ex)
{
    logger.Error(ex, "Operation failed for user {UserId} in context {Context}", 
        userId, operationContext);
    throw;
}

Integration with Dependency Injection

// Program.cs / Startup.cs
services.AddLogging(builder =>
{
    builder.AddConsole();
    builder.AddSerilog(); // or any other provider
});

// In your services
public class OrderService
{
    private readonly ILogger<OrderService> _logger;

    public OrderService(ILogger<OrderService> logger)
    {
        _logger = logger;
    }

    public async Task ProcessOrderAsync(int orderId)
    {
        using (_logger.TimeOperation("OrderProcessing"))
        {
            _logger.Information("Starting order processing for {OrderId}", orderId);
            
            try
            {
                // Processing logic
                _logger.Information("Order {OrderId} processed successfully", orderId);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Failed to process order {OrderId}", orderId);
                throw;
            }
        }
    }
}

Configuration

The library works with any ILogger implementation and follows standard .NET logging configuration:

// appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "System": "Warning"
    }
  }
}

Performance Considerations

  • All methods include automatic level checks to avoid expensive operations
  • Structured parameters use efficient formatting
  • Scopes are implemented with minimal overhead
  • Testing framework is optimized for fast test execution

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for a detailed history of changes.


Built with ❤️ by LayeredCraft

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on LayeredCraft.StructuredLogging:

Package Downloads
AlexaVoxCraft.MediatR

MediatR support for Alexa skill development, enabling clean request routing and handler composition.

AlexaVoxCraft.Logging

Provides Alexa-specific logging components including an AWS CloudWatch-compatible JSON formatter. Built on LayeredCraft.StructuredLogging.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0.6 204 6/26/2025
1.0.0.5 148 6/23/2025
1.0.0.4 283 6/10/2025
1.0.0.3 278 6/10/2025
1.0.0.2 261 6/9/2025
1.0.0.1 260 6/9/2025

Initial release of LayeredCraft.StructuredLogging with comprehensive logging extensions, scope management, enrichment capabilities, performance monitoring, and testing framework support.