Mariodbx.AspectLogging 2.0.0

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

AspectLogging

NuGet Version NuGet Downloads License: MIT .NET

A powerful Aspect-Oriented Programming (AOP) library for .NET that provides transparent, non-invasive logging of method calls using dynamic proxies. AspectLogging enables comprehensive observability without modifying your business logic.

Table of Contents

Overview

AspectLogging implements Aspect-Oriented Programming principles to separate cross-cutting concerns (logging) from business logic. It uses .NET's DispatchProxy to create dynamic proxies that intercept method calls, providing comprehensive logging without requiring changes to your existing codebase.

Core Capabilities

  • Transparent Interception: Automatically wraps service interfaces with logging behavior
  • Async/Await Support: Full support for asynchronous method interception
  • Configurable Behavior: Fine-grained control over what and how to log
  • HTTP Middleware: Optional middleware for request/response logging
  • Performance-Aware: Configurable performance thresholds and filtering
  • Structured Logging: Native support for structured logging with Microsoft.Extensions.Logging
  • Real-time Dashboard: Web-based dashboard for monitoring logs in real-time (like Hangfire)
  • Zero External Dependencies: Uses only Microsoft's built-in libraries

Architecture

System Architecture

graph TB
    subgraph "Client Layer"
        Controller[ASP.NET Controller]
        Consumer[Service Consumer]
    end
    
    subgraph "Proxy Layer"
        LoggingProxy[LoggingProxy&lt;T&gt;]
        DispatchProxy[DispatchProxy Base]
    end
    
    subgraph "Service Layer"
        Interface[IService Interface]
        Implementation[Service Implementation]
    end
    
    subgraph "Cross-Cutting Concerns"
        Logger[ILogger]
        HttpContext[HttpContextAccessor]
        Options[LoggingProxyOptions]
    end
    
    subgraph "Middleware Layer"
        LoggingMiddleware[HTTP Logging Middleware]
        Pipeline[ASP.NET Pipeline]
    end
    
    Controller --> LoggingProxy
    Consumer --> LoggingProxy
    LoggingProxy -.inherits.-> DispatchProxy
    LoggingProxy --> Interface
    Interface -.implemented by.-> Implementation
    LoggingProxy --> Logger
    LoggingProxy --> HttpContext
    LoggingProxy --> Options
    
    Pipeline --> LoggingMiddleware
    LoggingMiddleware --> Pipeline
    
    style LoggingProxy fill:#e1f5ff
    style Implementation fill:#fff4e1
    style Logger fill:#e8f5e9

Component Diagram

graph LR
    subgraph "AspectLogging Library"
        subgraph "Core Components"
            LP[LoggingProxy&lt;T&gt;]
            SCE[ServiceCollectionExtensions]
        end
        
        subgraph "Configuration"
            LPO[LoggingProxyOptions]
            Preset[LoggingPreset]
        end
        
        subgraph "Formatting"
            VF[ValueFormatter]
            TF[TypeFormatter]
        end
        
        subgraph "Attributes"
            NLA[NoLogAttribute]
        end
        
        subgraph "Middleware"
            LM[LoggingMiddleware]
        end
    end
    
    SCE --> LP
    SCE --> LPO
    SCE --> Preset
    LP --> LPO
    LP --> VF
    LP --> NLA
    VF --> TF
    
    style LP fill:#e1f5ff
    style SCE fill:#e1f5ff
    style LPO fill:#fff4e1

Key Features

1. Dynamic Proxy Interception

AspectLogging uses DispatchProxy to create runtime proxies that wrap your service interfaces:

sequenceDiagram
    participant Client
    participant Proxy as LoggingProxy
    participant Logger
    participant Service as Service Implementation
    
    Client->>Proxy: CallMethod(args)
    activate Proxy
    Proxy->>Logger: Log Entry (Method, Args)
    Proxy->>Service: Invoke Method(args)
    activate Service
    
    alt Success
        Service-->>Proxy: Return Result
        Proxy->>Logger: Log Exit (Duration, Result)
        Proxy-->>Client: Return Result
    else Exception
        Service--xProxy: Throw Exception
        Proxy->>Logger: Log Exception (Duration, Error)
        Proxy--xClient: Rethrow Exception
    end
    
    deactivate Service
    deactivate Proxy

2. Asynchronous Method Support

Full support for Task and Task<T> return types with proper async/await handling:

sequenceDiagram
    participant Client
    participant Proxy as LoggingProxy<IService>
    participant Logger
    participant Service as Async Service
    
    Client->>Proxy: CallAsyncMethod()
    activate Proxy
    
    Proxy->>Logger: Log Entry
    Proxy->>Service: Invoke Async Method
    Note over Proxy: Start Stopwatch
    
    Proxy-->>Client: Return Task
    deactivate Proxy
    
    Note over Service: Async Operation
    
    Service-->>Proxy: Task Completes
    activate Proxy
    Note over Proxy: Stop Stopwatch
    Proxy->>Logger: Log Exit (Duration, Result)
    deactivate Proxy

3. Dependency Injection Integration

Seamless integration with Microsoft.Extensions.DependencyInjection:

graph TD
    subgraph "Service Registration Flow"
        A[IServiceCollection] --> B{AddAspectLogging}
        B --> C[Scan Registered Services]
        C --> D{Is Interface?}
        D -->|Yes| E{Matches Namespace?}
        D -->|No| F[Skip]
        E -->|Yes| G{Is Excluded?}
        E -->|No| F
        G -->|No| H[Create Proxy Decorator]
        G -->|Yes| F
        H --> I[Replace Service Registration]
        I --> J[Original Service as Decorated]
        J --> K[Proxy as Service]
    end
    
    style B fill:#e1f5ff
    style H fill:#e1f5ff
    style K fill:#c8e6c9

4. Real-time Logging Dashboard

Monitor your application's logs in real-time through a web-based dashboard:

graph TD
    subgraph "Dashboard Architecture"
        A[ASP.NET MVC] --> B[SignalR Hub]
        B --> C[DashboardLoggerProvider]
        C --> D[In-Memory Log Store]
        D --> E[Configurable Buffer]
        
        F[Web Client] --> G[SignalR Connection]
        G --> B
        F --> H[REST API]
        H --> I[Log Filtering & Search]
        
        J[Application Logs] --> C
    end
    
    style B fill:#e1f5ff
    style D fill:#fff4e1
    style G fill:#c8e6c9

Features:

  • Real-time log streaming via SignalR
  • Configurable log buffer size
  • RESTful API for log retrieval
  • Web-based UI for monitoring
  • Log filtering and search capabilities

5. Persistent Database Storage

Store logs and performance metrics in a database for long-term analysis:

graph TD
    subgraph "Database Storage"
        A[Application] --> B[DatabaseLoggerProvider]
        B --> C[Batch Processing]
        C --> D[AspectLoggingDbContext]
        D --> E[(Database)]
        
        F[Dashboard] --> G[REST API]
        G --> D
        F --> H[Statistics Queries]
        H --> I[Method Performance]
        H --> J[Error Analysis]
    end
    
    style D fill:#e1f5ff
    style E fill:#fff4e1

Supported Databases:

  • SQLite (default, file-based)
  • SQL Server
  • MySQL
  • PostgreSQL

Features:

  • Automatic schema creation
  • Method call statistics tracking
  • Performance metrics collection
  • Slowest queries analysis
  • Configurable data retention

Installation

Install via NuGet Package Manager:

dotnet add package Mariodbx.AspectLogging

Or via Package Manager Console:

Install-Package Mariodbx.AspectLogging

Quick Start

Basic Setup

using AspectLogging;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Register your services
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IOrderService, OrderService>();

// Add aspect logging with auto-detection
builder.Services.AddAspectLogging();

var app = builder.Build();

With Specific Namespaces

// Only log services in specific namespaces
builder.Services.AddAspectLogging("MyCompany.Services", "MyCompany.Repositories");

With Presets

// Development: Verbose logging, all details
builder.Services.AddAspectLogging(LoggingPreset.Development);

// Production: Exceptions and slow operations only
builder.Services.AddAspectLogging(LoggingPreset.Production);

// Balanced: Recommended for most scenarios
builder.Services.AddAspectLogging(LoggingPreset.Balanced);

Add Database Storage (Optional)

For persistent storage and analytics, add database support:

// SQLite (default)
builder.Services.AddAspectLoggingDatabase();

// SQL Server
builder.Services.AddAspectLoggingSqlServer("Server=...;Database=...;");

// MySQL
builder.Services.AddAspectLoggingMySql("Server=...;Database=...;");

// PostgreSQL
builder.Services.AddAspectLoggingPostgreSql("Host=...;Database=...;");

Add Real-time Dashboard (Optional)

// In ConfigureServices
builder.Services.AddAspectLoggingDashboard(maxLogEntries: 2000);

// In Configure (after UseRouting)
app.UseAspectLoggingDashboard("/logging");

Access the dashboard at: https://yourapp/logging

Configuration

Configuration via Code

builder.Services.AddLoggingProxyForInterfaces(options =>
{
    options.Enabled = true;
    options.IncludeNamespacePrefixes = new[] { "MyApp" };
    options.LogEntry = true;
    options.LogExit = true;
    options.LogExceptions = true;
    options.LogDetailedArgs = true;
    options.LogDetailedReturns = true;
    options.MinimumDurationMs = 10;
    options.MaxReturnValueLength = 500;
    options.EntryLogLevel = LogLevel.Information;
    options.ExitLogLevel = LogLevel.Information;
    options.ExceptionLogLevel = LogLevel.Error;
});

Configuration via appsettings.json

{
  "LoggingProxy": {
    "Enabled": true,
    "IncludeNamespacePrefixes": ["MyApp.Services", "MyApp.Repositories"],
    "ExcludedServiceTypeFullNames": ["MyApp.Services.IHealthCheckService"],
    "IgnoredMethods": ["MyApp.Services.IUserService.GetUserTypesAsync"],
    "LogEntry": true,
    "LogExit": true,
    "LogExceptions": true,
    "LogDetailedArgs": true,
    "LogDetailedReturns": true,
    "MinimumDurationMs": 10,
    "MaxReturnValueLength": 500,
    "IncludeRequestId": true,
    "UseStructuredLogging": true,
    "SwallowLoggingErrors": true
  }
}

Configuration Options Reference

Option Type Default Description
Enabled bool true Enable/disable logging proxy globally
IncludeNamespacePrefixes string[] ["AspectLogging"] Only wrap services matching these namespace prefixes
ExcludedServiceTypeFullNames string[] [] Service types to never wrap
IgnoredMethods string[] [] Specific methods to exclude from logging
LogEntry bool true Log method entry
LogExit bool true Log method exit
LogExceptions bool true Log exceptions
LogDetailedArgs bool true Log detailed argument values (vs. type names only)
LogDetailedReturns bool true Log detailed return values (vs. type name only)
MinimumDurationMs long 0 Only log methods taking longer than this (milliseconds)
MaxReturnValueLength int 500 Maximum length for logged values (truncates beyond)
IncludeRequestId bool true Include HTTP request ID in logs
UseStructuredLogging bool true Use structured logging format
EntryLogLevel LogLevel Information Log level for entry messages
ExitLogLevel LogLevel Information Log level for exit messages
ExceptionLogLevel LogLevel Error Log level for exception messages
PerformanceThresholdMs long 1000 Threshold for performance warnings

Logging Presets

graph TD
    subgraph "Development Preset"
        D1[LogEntry: true]
        D2[LogExit: true]
        D3[LogDetailedArgs: true]
        D4[LogDetailedReturns: true]
        D5[MinimumDurationMs: 0]
        D6[EntryLogLevel: Debug]
    end
    
    subgraph "Balanced Preset"
        B1[LogEntry: true]
        B2[LogExit: true]
        B3[LogDetailedArgs: true]
        B4[LogDetailedReturns: true]
        B5[MinimumDurationMs: 10]
        B6[EntryLogLevel: Information]
    end
    
    subgraph "Production Preset"
        P1[LogEntry: false]
        P2[LogExit: true]
        P3[LogDetailedArgs: false]
        P4[LogDetailedReturns: false]
        P5[MinimumDurationMs: 100]
        P6[ExitLogLevel: Warning]
    end
    
    subgraph "Minimal Preset"
        M1[LogEntry: false]
        M2[LogExit: false]
        M3[LogExceptions: true]
        M4[LogDetailedArgs: false]
        M5[LogDetailedReturns: false]
    end

Advanced Usage

Excluding Specific Methods

Use the [NoLog] attribute to exclude methods from logging:

public interface IUserService
{
    Task<User> GetUserAsync(int id);
    
    [NoLog]
    Task<string> GetPasswordHashAsync(int userId); // Not logged
}

Custom Type Formatting

The library automatically formats complex types. For collections:

// Input: List<int> { 1, 2, 3, 4, 5 }
// Output: List<int>[5] { 1, 2, 3, 4, 5 }

// Input: Dictionary<string, object>
// Output: Dictionary<string, object>[3] { Key1=Value1, Key2=Value2, Key3=Value3 }

For custom types, properties are serialized:

// Input: User { Id = 1, Name = "John", Email = "john@example.com" }
// Output: User { Id: 1, Name: "John", Email: "john@example.com" }

Performance Filtering

Filter logs based on execution duration:

options.MinimumDurationMs = 50; // Only log methods taking >= 50ms
options.PerformanceThresholdMs = 1000; // Log as Warning if >= 1 second

Structured Logging with Request Correlation

options.IncludeRequestId = true;
options.UseStructuredLogging = true;

Log output includes structured properties:

{
  "Timestamp": "2025-11-25T10:30:45.123Z",
  "Level": "Information",
  "MessageTemplate": "Exit {Method} (ms={Elapsed}) with return {@Return}",
  "Properties": {
    "Method": "MyApp.Services.IUserService.GetUserAsync",
    "Elapsed": 45,
    "Return": { "Id": 1, "Name": "John" },
    "RequestId": "0HMVQK8B7QKQJ:00000001"
  }
}

Logging Dashboard

AspectLogging includes a real-time web-based dashboard for monitoring logs, similar to Hangfire's dashboard. The dashboard provides:

  • Real-time log streaming using SignalR
  • Filtering by log level and text search
  • Request isolation by RequestId
  • Clear logs functionality
  • Responsive design for desktop and mobile

Setup

  1. Register the dashboard in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
    services.AddAspectLogging();
    services.AddAspectLoggingDashboard(maxLogEntries: 2000);
}
  1. Enable the dashboard in the middleware pipeline:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ... other middleware
    
    app.UseAspectLoggingDashboard("/logging");
}
  1. Access the dashboard at https://yourapp/logging

Dashboard Features

  • Live Updates: New logs appear instantly without page refresh
  • Filtering: Filter by log level (Debug, Info, Warning, Error, Critical) or search text
  • Request Tracing: Group logs by RequestId to trace complete request flows
  • Performance: Keeps last N entries in memory (configurable)
  • API Endpoints:
    • GET /logging/api/logs - Get current logs as JSON
    • POST /logging/api/clear - Clear all logs

Example Usage

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services
builder.Services.AddControllers();
builder.Services.AddAspectLogging();
builder.Services.AddAspectLoggingDashboard();

var app = builder.Build();

// Configure middleware
app.UseRouting();
app.UseAspectLoggingDashboard();
app.UseEndpoints(endpoints => endpoints.MapControllers());

How It Works

Method Interception Flow

flowchart TD
    A[Method Call] --> B{Has NoLog?}
    B -->|Yes| C[Direct Invocation]
    B -->|No| D{In Ignored Methods?}
    D -->|Yes| C
    D -->|No| E[Start Stopwatch]
    E --> F{LogEntry Enabled?}
    F -->|Yes| G[Log Entry with Args]
    F -->|No| H[Invoke Target Method]
    G --> H
    
    H --> I{Returns Task?}
    I -->|Yes| J[Async Interception]
    I -->|No| K[Synchronous Handling]
    
    J --> L[Attach Continuation]
    L --> M{Task Completes?}
    M -->|Success| N[Log Exit with Result]
    M -->|Faulted| O[Log Exception]
    N --> P[Return Result]
    O --> Q[Rethrow Exception]
    
    K --> R{Exception Thrown?}
    R -->|Yes| S[Stop Stopwatch]
    R -->|No| T[Stop Stopwatch]
    S --> U{LogExceptions?}
    T --> V{LogExit and Duration OK?}
    U -->|Yes| W[Log Exception]
    V -->|Yes| X[Log Exit]
    W --> Q
    X --> P
    U -->|No| Q
    V -->|No| P
    
    C --> P
    
    style E fill:#e1f5ff
    style G fill:#e1f5ff
    style N fill:#e1f5ff
    style O fill:#ffcdd2
    style W fill:#ffcdd2

Service Registration Process

sequenceDiagram
    participant App as Application Code
    participant DI as IServiceCollection
    participant Ext as ServiceCollectionExtensions
    participant Factory as Proxy Factory
    
    App->>DI: AddScoped<IService, Service>()
    App->>Ext: AddAspectLogging()
    activate Ext
    
    Ext->>DI: Get All Descriptors
    DI-->>Ext: ServiceDescriptor[]
    
    loop For Each Service
        Ext->>Ext: Is Interface & Matches Namespace?
        alt Should Wrap
            Ext->>Factory: Create Proxy Factory
            Factory-->>Ext: Func<IServiceProvider, IService>
            Ext->>DI: Remove Original Descriptor
            Ext->>DI: Register Decorated (Original)
            Ext->>DI: Register Proxy (Interface)
        else Skip
            Note over Ext: Leave Original Registration
        end
    end
    
    deactivate Ext
    
    App->>DI: Build ServiceProvider
    DI-->>App: IServiceProvider
    
    App->>DI: GetService<IService>()
    DI->>Factory: Create Proxy
    Factory->>DI: Resolve Decorated Service
    DI-->>Factory: Original Service Instance
    Factory->>Factory: Create LoggingProxy<IService>
    Factory->>Factory: Initialize with Decorated, Logger, Options
    Factory-->>DI: Proxy Instance
    DI-->>App: LoggingProxy<IService>

Async Method Interception

flowchart TD
    A[Async Method Invoked] --> B[Log Entry]
    B --> C[Invoke Target Method]
    C --> D[Receive Task]
    D --> E{Task<T> or Task?}
    
    E -->|Task<T>| F[Use Generic Interception]
    E -->|Task| G[Use Non-Generic Interception]
    
    F --> H[Create Continuation Task]
    G --> I[Create Continuation Task]
    
    H --> J[Return Task to Caller]
    I --> J
    
    subgraph "Background Continuation"
        K[Await Original Task]
        K --> L{Success?}
        L -->|Yes| M[Get Result]
        L -->|Exception| N[Catch Exception]
        M --> O[Stop Stopwatch]
        N --> P[Stop Stopwatch]
        O --> Q{Duration >= Min?}
        Q -->|Yes| R[Log Exit with Result]
        Q -->|No| S[Skip Logging]
        R --> T[Return Result]
        S --> T
        P --> U[Log Exception]
        U --> V[Rethrow]
    end
    
    J -.continuation.-> K
    
    style H fill:#e1f5ff
    style I fill:#e1f5ff
    style R fill:#c8e6c9
    style U fill:#ffcdd2

HTTP Middleware Flow

sequenceDiagram
    participant Client
    participant Middleware as LoggingMiddleware
    participant Logger
    participant Next as Next Middleware
    participant App as Application
    
    Client->>Middleware: HTTP Request
    activate Middleware
    
    Middleware->>Logger: Log Request (Method, Path, QueryString)
    Note over Middleware: Start Stopwatch
    
    alt Has Request Body
        Middleware->>Middleware: Buffer & Read Body
        Middleware->>Logger: Log Request Body
    end
    
    Middleware->>Next: InvokeAsync(context)
    activate Next
    Next->>App: Process Request
    App-->>Next: Response
    Next-->>Middleware: Continue
    deactivate Next
    
    Note over Middleware: Stop Stopwatch
    
    Middleware->>Logger: Log Response (Status, Duration)
    
    alt Has Response Body
        Middleware->>Middleware: Read Response Body
        Middleware->>Logger: Log Response Body
    end
    
    Middleware-->>Client: HTTP Response
    deactivate Middleware

Dashboard Operation Flow

sequenceDiagram
    participant Client as Web Browser
    participant MVC as ASP.NET MVC
    participant Hub as LoggingHub
    participant Provider as DashboardLoggerProvider
    participant Store as In-Memory Store
    
    Client->>MVC: GET /logging
    MVC-->>Client: Dashboard HTML
    
    Client->>Hub: SignalR Connect
    activate Hub
    Hub->>Provider: Subscribe to Updates
    Provider-->>Hub: Initial Log Batch
    Hub-->>Client: Send Initial Logs
    
    loop Real-time Updates
        Provider->>Hub: New Log Entry
        Hub->>Client: Push Log Update
    end
    
    Client->>MVC: GET /logging/api/logs?filter=...
    MVC->>Provider: Query Logs
    Provider->>Store: Filter & Search
    Store-->>Provider: Filtered Results
    Provider-->>MVC: JSON Response
    MVC-->>Client: Filtered Logs

Performance Considerations

Overhead Analysis

graph LR
    subgraph "Performance Impact Factors"
        A[Proxy Creation] -->|One-time| B[Negligible]
        C[Method Interception] -->|Per Call| D[Minimal]
        E[Logging Operations] -->|Per Call| F[Configurable]
        G[Formatting] -->|Per Value| H[Moderate]
    end
    
    subgraph "Optimization Strategies"
        I[Use MinimumDurationMs]
        J[Disable DetailedArgs/Returns]
        K[Use Production Preset]
        L[Exclude High-Frequency Methods]
        M[Use Async Logging]
    end
    
    F --> I
    F --> J
    F --> K
    H --> L
    D --> M
    
    style I fill:#c8e6c9
    style J fill:#c8e6c9
    style K fill:#c8e6c9
    style L fill:#c8e6c9
    style M fill:#c8e6c9

Recommendations

  1. Development Environment: Use Development preset for maximum observability
  2. Staging Environment: Use Balanced preset with appropriate duration thresholds
  3. Production Environment: Use Production preset, log exceptions and slow operations
  4. High-Performance Scenarios: Use Minimal preset or exclude specific services

Benchmarks

Typical overhead per method call:

  • Without detailed logging: < 1 microsecond
  • With detailed logging: 5-50 microseconds (depends on argument complexity)
  • Async method interception: < 1 microsecond additional overhead

API Reference

Core Classes

LoggingProxy<T>

Dynamic proxy that intercepts method calls on interface T.

Key Methods:

  • Initialize(T decorated, ILogger logger, Type serviceInterfaceType, LoggingProxyOptions options, IHttpContextAccessor httpContextAccessor)
  • Invoke(MethodInfo targetMethod, object[] args) - Core interception point
ServiceCollectionExtensions

Extension methods for registering logging proxies with DI container.

Methods:

// Auto-detect namespaces and use preset
IServiceCollection AddAspectLogging(
    this IServiceCollection services, 
    LoggingPreset preset = LoggingPreset.Balanced)

// Specify namespaces with preset
IServiceCollection AddAspectLogging(
    this IServiceCollection services, 
    LoggingPreset preset, 
    params string[] namespaces)

// Manual configuration
IServiceCollection AddLoggingProxyForInterfaces(
    this IServiceCollection services,
    Action<LoggingProxyOptions> configure)

// Configuration from IConfiguration
IServiceCollection AddLoggingProxyForInterfaces(
    this IServiceCollection services,
    IConfiguration configuration,
    string sectionName = "LoggingProxy")
LoggingProxyOptions

Configuration options for proxy behavior. See Configuration Options Reference.

LoggingMiddleware

ASP.NET Core middleware for HTTP request/response logging.

Constructor:

public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)

Dashboard APIs

ServiceCollectionExtensions (Dashboard)

Extension methods for registering the logging dashboard.

Methods:

// Register dashboard with default settings
IServiceCollection AddAspectLoggingDashboard(
    this IServiceCollection services)

// Register dashboard with custom buffer size
IServiceCollection AddAspectLoggingDashboard(
    this IServiceCollection services, 
    int maxLogEntries = 1000)

// Register dashboard with custom route
IApplicationBuilder UseAspectLoggingDashboard(
    this IApplicationBuilder app, 
    string routePrefix = "/logging")
LoggingHub

SignalR hub for real-time log streaming.

Methods:

  • Task SubscribeToLogs() - Subscribe to real-time log updates
  • Task UnsubscribeFromLogs() - Unsubscribe from log updates
DashboardLoggerProvider

In-memory logger provider that buffers logs for the dashboard.

Constructor:

public DashboardLoggerProvider(
    int maxLogEntries = 1000, 
    LogLevel minimumLevel = LogLevel.Information)
DashboardController

REST API controller for log retrieval and filtering.

Endpoints:

  • GET /api/logs - Get all logs with optional filtering
  • GET /api/logs/{id} - Get specific log entry
  • DELETE /api/logs - Clear all logs

Query Parameters:

  • level - Filter by log level (Information, Warning, Error, etc.)
  • category - Filter by logger category
  • search - Search in message text
  • from - Start date/time (ISO 8601)
  • to - End date/time (ISO 8601)
  • skip - Number of entries to skip
  • take - Maximum number of entries to return

Database Classes

AspectLoggingDbContext

Entity Framework Core database context for AspectLogging.

Key Methods:

  • EnsureDatabaseCreatedAsync() - Creates database and schema
  • GetLogsAsync(...) - Query logs with filtering
  • GetSlowestMethodsAsync(int top) - Get slowest method calls
  • GetMostCalledMethodsAsync(int top) - Get most frequently called methods
  • UpdateMethodStatsAsync(string className, string methodName, long durationMs, bool success) - Update method statistics
DatabaseLoggerProvider

Database-backed logger provider that persists logs and collects statistics.

Configuration Options:

  • Provider - Database provider (Sqlite, SqlServer, MySql, PostgreSql)
  • ConnectionString - Database connection string
  • EnableAutoMigrations - Whether to enable automatic migrations
  • LogRetentionDays - Days to keep log entries
  • MetricsRetentionDays - Days to keep performance metrics

Attributes

[NoLog]

Opt-out attribute to exclude methods, interfaces, or classes from logging.

Usage:

[NoLog]
public interface ISensitiveService { ... }

public interface IUserService
{
    [NoLog]
    Task<string> GetPasswordHashAsync(int userId);
}

Formatters

ValueFormatter

Formats values for logging with intelligent handling of collections, primitives, and custom types.

Configuration:

public ValueFormatter(
    int maxCollectionItems = 10, 
    int maxPropertyCount = 10)
TypeFormatter

Provides human-readable type names for generic types.

Example:

TypeFormatter.GetFriendlyTypeName(typeof(List<int>)) 
// Returns: "List<int>"

TypeFormatter.GetFriendlyTypeName(typeof(Dictionary<string, List<User>>))
// Returns: "Dictionary<string, List<User>>"

System Requirements

  • .NET: 8.0 or higher
  • Dependencies:
    • Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
    • Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
    • Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
    • Dashboard Dependencies (optional):
      • Microsoft.AspNetCore.SignalR (>= 8.0.0)
      • Microsoft.AspNetCore.Mvc (>= 8.0.0)
      • System.Text.Json (>= 8.0.0)
    • Database Dependencies (optional):
      • Microsoft.EntityFrameworkCore (>= 8.0.0)
      • Microsoft.EntityFrameworkCore.SqlServer (>= 8.0.0) - for SQL Server
      • Pomelo.EntityFrameworkCore.MySql (>= 8.0.0) - for MySQL
      • Npgsql.EntityFrameworkCore.PostgreSQL (>= 8.0.0) - for PostgreSQL

Contributing

Contributions are welcome. Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

Development Setup

  1. Clone the repository
  2. Restore dependencies: dotnet restore
  3. Build the solution: dotnet build
  4. Run tests: dotnet test

License

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

Acknowledgments

  • Built on .NET's DispatchProxy for dynamic proxy generation
  • Designed for integration with Microsoft.Extensions.Logging
  • Optimized for Microsoft.Extensions.Logging structured logging

Support

For issues, questions, or contributions, please visit:


Version: 1.0.1
Author: Mario De Benedictis
Repository: https://github.com/mariodbx/aspect-logging

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
3.1.0 708 12/3/2025
3.0.1 687 12/3/2025
3.0.0 598 12/1/2025
2.0.0 217 11/27/2025
1.4.1 605 12/1/2025
1.0.1 216 11/27/2025
1.0.0 215 11/25/2025

v1.0.1 - Major Feature Update
     - Real-time logging dashboard with SignalR and web UI
     - Database storage with multi-provider support (SQLite, SQL Server, MySQL, PostgreSQL)
     - Method call statistics and performance analytics (slowest queries, call counts, success rates)
     - Automatic database schema creation (like Hangfire)
     - REST API for log querying and statistics
     - Modern JSON handling with System.Text.Json
     - Zero external dependencies (Microsoft libraries only)
     - Enhanced dashboard with statistics visualization

     v1.0.0 - Initial release
     - Dynamic proxy-based method interception
     - Configurable via code or appsettings.json
     - Async method support
     - Custom type and value formatting
     - HTTP middleware for request/response logging
     - Performance thresholds and filtering
     - Structured logging support