DotNetBrightener.ActivityLog
                             
                            
                                2025.0.9
                            
                        
                    See the version list below for details.
dotnet add package DotNetBrightener.ActivityLog --version 2025.0.9
NuGet\Install-Package DotNetBrightener.ActivityLog -Version 2025.0.9
<PackageReference Include="DotNetBrightener.ActivityLog" Version="2025.0.9" />
<PackageVersion Include="DotNetBrightener.ActivityLog" Version="2025.0.9" />
<PackageReference Include="DotNetBrightener.ActivityLog" />
paket add DotNetBrightener.ActivityLog --version 2025.0.9
#r "nuget: DotNetBrightener.ActivityLog, 2025.0.9"
#:package DotNetBrightener.ActivityLog@2025.0.9
#addin nuget:?package=DotNetBrightener.ActivityLog&version=2025.0.9
#tool nuget:?package=DotNetBrightener.ActivityLog&version=2025.0.9
Activity Logging for .NET
Automatically track and log method execution in your .NET applications with a simple attribute. Perfect for monitoring business operations, debugging issues, and maintaining audit trails.
What It Does
Activity Logging captures detailed information about your method calls including:
- Execution timing - How long methods take to run
- Input parameters - What data was passed to methods
- Return values - What methods returned
- Exceptions - Any errors that occurred
- User context - Who performed the action
- Performance metrics - Identify slow operations
Key Benefits
- ✅ Zero code changes - Just add [LogActivity]attributes
- ✅ Automatic tracking - No manual logging code required
- ✅ Performance monitoring - Built-in slow method detection
- ✅ Exception capture - Comprehensive error tracking
- ✅ Async support - Works with async/await methods
- ✅ Configurable - Control what gets logged and how
- ✅ Multiple databases - SQL Server, PostgreSQL, or in-memory
Quick Start
1. Install the Package
# Core module
dotnet add package DotNetBrightener.ActivityLog
# Choose a database provider (optional)
dotnet add package DotNetBrightener.ActivityLog.DataStorage.SqlServer
# OR
dotnet add package DotNetBrightener.ActivityLog.DataStorage.PostgreSql
2. Configure Your Application
Add this to your Program.cs or Startup.cs:
// Basic setup (logs to console/file only)
services.AddActivityLogging();
// With database storage
services.AddActivityLogging()
        .WithStorage()
        .UseSqlServer("your-connection-string");
3. Add Configuration (Optional)
Add to your appsettings.json:
{
  "ActivityLogging": {
    "IsEnabled": true,
    "MinimumLogLevel": "Information",
    "Performance": {
      "SlowMethodThresholdMs": 1000
    },
    "Serialization": {
      "ExcludedProperties": ["Password", "Secret", "Token"]
    }
  }
}
4. Register Your Services
// Register services that should be logged
services.AddActivityLoggedService<IUserService, UserService>();
services.AddActivityLoggedService<IOrderService, OrderService>();
5. Start Logging
Add the [LogActivity] attribute to methods you want to track:
public class UserService : IUserService
{
    [LogActivity("GetUser", "Retrieved user {userId}")]
    public async Task<User> GetUserAsync(int userId)
    {
        return await _repository.GetByIdAsync(userId);
    }
}
That's it! Your methods are now being logged automatically.
Basic Usage Examples
Simple Method Logging
public class UserService : IUserService
{
    [LogActivity("GetUser", "Getting user {userId}")]
    public async Task<User> GetUserAsync(int userId)
    {
        return await _repository.GetByIdAsync(userId);
    }
    [LogActivity("CreateUser", "Creating user {request.Name}")]
    public async Task<User> CreateUserAsync(CreateUserRequest request)
    {
        var user = new User { Name = request.Name, Email = request.Email };
        return await _repository.CreateAsync(user);
    }
}
Different Logging Scenarios
public class OrderService : IOrderService
{
    // Log with custom activity name
    [LogActivity("ProcessOrder")]
    public async Task ProcessOrderAsync(int orderId)
    {
        // Implementation
    }
    // Log with description template
    [LogActivity("CancelOrder", "Cancelled order {orderId} for user {userId}")]
    public async Task CancelOrderAsync(int orderId, int userId)
    {
        // Implementation
    }
    // Log synchronous methods too
    [LogActivity("ValidateOrder", "Validating order data")]
    public bool ValidateOrder(Order order)
    {
        return order.IsValid();
    }
}
Adding Runtime Context
You can add extra information to your logs during method execution:
public class OrderService : IOrderService
{
    [LogActivity("ProcessPayment", "Processing payment for order {orderId}")]
    public async Task ProcessPaymentAsync(int orderId, decimal amount)
    {
        // Add custom metadata during execution
        ActivityLogContext.AddMetadata("paymentAmount", amount);
        ActivityLogContext.AddMetadata("processingStartTime", DateTime.UtcNow);
        // Process payment logic here
        var result = await _paymentService.ProcessAsync(orderId, amount);
        // Add more context based on results
        ActivityLogContext.AddMetadata("paymentResult", result.Status);
        ActivityLogContext.AddMetadata("transactionId", result.TransactionId);
        // You can even modify the activity details
        if (result.IsSuccess)
        {
            ActivityLogContext.SetActivityDescription($"Successfully processed ${amount} payment");
        }
        else
        {
            ActivityLogContext.SetActivityDescription($"Failed to process ${amount} payment: {result.Error}");
        }
    }
}
Batch Metadata Addition
[LogActivity("AnalyzeData", "Analyzing customer data")]
public async Task AnalyzeCustomerDataAsync(int customerId)
{
    // Add multiple pieces of metadata at once
    var metadata = new Dictionary<string, object?>
    {
        ["customerId"] = customerId,
        ["analysisType"] = "comprehensive",
        ["startTime"] = DateTime.UtcNow,
        ["version"] = "2.1"
    };
    ActivityLogContext.AddMetadata(metadata);
    // Your analysis logic here
}
Configuration Options
Basic Configuration
Control what gets logged and how:
{
  "ActivityLogging": {
    "IsEnabled": true,
    "MinimumLogLevel": "Information"
  }
}
Performance Settings
Monitor and optimize slow methods:
{
  "ActivityLogging": {
    "Performance": {
      "SlowMethodThresholdMs": 1000,
      "LogOnlySlowMethods": false,
      "EnableHighPrecisionTiming": true
    }
  }
}
Data Protection
Exclude sensitive information from logs:
{
  "ActivityLogging": {
    "Serialization": {
      "ExcludedProperties": ["Password", "Secret", "Token", "ApiKey"],
      "ExcludedTypes": ["System.IO.Stream", "Microsoft.AspNetCore.Http.HttpContext"],
      "MaxDepth": 3,
      "MaxStringLength": 1000,
      "SerializeInputParameters": true,
      "SerializeReturnValues": true
    }
  }
}
Filtering Options
Control which methods get logged:
{
  "ActivityLogging": {
    "Filtering": {
      "ExcludedNamespaces": ["System", "Microsoft"],
      "ExcludedMethods": ["ToString", "GetHashCode", "Equals"],
      "UseWhitelistMode": false
    }
  }
}
Background Processing
Configure async logging for better performance:
{
  "ActivityLogging": {
    "AsyncLogging": {
      "EnableAsyncLogging": true,
      "BatchSize": 100,
      "FlushIntervalMs": 5000,
      "MaxQueueSize": 10000
    }
  }
}
Common Scenarios
E-commerce Application
public class OrderService : IOrderService
{
    [LogActivity("CreateOrder", "Creating order for customer {customerId}")]
    public async Task<Order> CreateOrderAsync(int customerId, List<OrderItem> items)
    {
        ActivityLogContext.AddMetadata("itemCount", items.Count);
        ActivityLogContext.AddMetadata("totalAmount", items.Sum(i => i.Price * i.Quantity));
        var order = await _repository.CreateAsync(new Order
        {
            CustomerId = customerId,
            Items = items
        });
        ActivityLogContext.AddMetadata("orderId", order.Id);
        return order;
    }
    [LogActivity("ProcessPayment", "Processing payment for order {orderId}")]
    public async Task<PaymentResult> ProcessPaymentAsync(int orderId, PaymentInfo payment)
    {
        ActivityLogContext.AddMetadata("paymentMethod", payment.Method);
        ActivityLogContext.AddMetadata("amount", payment.Amount);
        try
        {
            var result = await _paymentService.ProcessAsync(payment);
            ActivityLogContext.AddMetadata("transactionId", result.TransactionId);
            ActivityLogContext.AddMetadata("status", result.Status);
            return result;
        }
        catch (PaymentException ex)
        {
            ActivityLogContext.AddMetadata("paymentError", ex.Message);
            throw;
        }
    }
}
User Management
public class UserService : IUserService
{
    [LogActivity("RegisterUser", "Registering new user {email}")]
    public async Task<User> RegisterUserAsync(string email, string password)
    {
        ActivityLogContext.AddMetadata("registrationSource", "web");
        ActivityLogContext.AddMetadata("timestamp", DateTime.UtcNow);
        var user = await _repository.CreateAsync(new User { Email = email });
        ActivityLogContext.SetTargetEntity($"User:{user.Id}");
        return user;
    }
    [LogActivity("UpdateProfile", "Updating profile for user {userId}")]
    public async Task UpdateProfileAsync(int userId, UserProfile profile)
    {
        ActivityLogContext.AddMetadata("fieldsUpdated", profile.GetChangedFields());
        ActivityLogContext.SetTargetEntity($"User:{userId}");
        await _repository.UpdateAsync(userId, profile);
    }
}
Database Setup
SQL Server
// In Program.cs
services.AddActivityLogging()
        .WithStorage()
        .UseSqlServer("Server=localhost;Database=MyApp;Trusted_Connection=true;");
Run migrations to create the database tables:
dotnet ef database update --project YourProject
PostgreSQL
// In Program.cs
services.AddActivityLogging()
        .WithStorage()
        .UsePostgreSql("Host=localhost;Database=myapp;Username=postgres;Password=password");
In-Memory (for Testing)
// Perfect for unit tests and development
services.AddActivityLogging()
        .WithStorage()
        .UseInMemoryDatabase("TestDatabase");
Best Practices
1. Use Meaningful Activity Names
// ✅ Good - describes the business operation
[LogActivity("ProcessRefund", "Processing refund for order {orderId}")]
// ❌ Avoid - too generic
[LogActivity("DoWork", "Doing some work")]
2. Include Important Context
[LogActivity("SendEmail", "Sending {emailType} email to {recipientEmail}")]
public async Task SendEmailAsync(string emailType, string recipientEmail, string content)
{
    // Add extra context during execution
    ActivityLogContext.AddMetadata("emailSize", content.Length);
    ActivityLogContext.AddMetadata("templateVersion", GetTemplateVersion(emailType));
    await _emailService.SendAsync(recipientEmail, content);
}
3. Protect Sensitive Data
{
  "ActivityLogging": {
    "Serialization": {
      "ExcludedProperties": [
        "Password", "Secret", "Token", "ApiKey",
        "CreditCardNumber", "SSN", "PersonalData"
      ]
    }
  }
}
4. Monitor Performance Impact
{
  "ActivityLogging": {
    "Performance": {
      "LogOnlySlowMethods": true,
      "SlowMethodThresholdMs": 500
    },
    "AsyncLogging": {
      "EnableAsyncLogging": true
    }
  }
}
5. Use Appropriate Log Levels
// Critical business operations
[LogActivity("ProcessPayment", "Processing payment", LogLevel = ActivityLogLevel.Warning)]
// Regular operations
[LogActivity("GetUser", "Getting user data", LogLevel = ActivityLogLevel.Information)]
// Detailed debugging
[LogActivity("ValidateInput", "Validating input", LogLevel = ActivityLogLevel.Debug)]
Performance Tips
For High-Traffic Applications
{
  "ActivityLogging": {
    "Performance": {
      "LogOnlySlowMethods": true,
      "SlowMethodThresholdMs": 500
    },
    "AsyncLogging": {
      "EnableAsyncLogging": true,
      "BatchSize": 500,
      "FlushIntervalMs": 2000
    },
    "Serialization": {
      "MaxDepth": 2,
      "MaxStringLength": 500
    }
  }
}
Exclude Noisy Methods
{
  "ActivityLogging": {
    "Filtering": {
      "ExcludedNamespaces": ["System", "Microsoft", "Newtonsoft"],
      "ExcludedMethods": ["ToString", "GetHashCode", "Equals", "Dispose"]
    }
  }
}
Development vs Production
// Development - log everything
{
  "ActivityLogging": {
    "IsEnabled": true,
    "MinimumLogLevel": "Debug",
    "Performance": {
      "LogOnlySlowMethods": false
    }
  }
}
// Production - log only important operations
{
  "ActivityLogging": {
    "IsEnabled": true,
    "MinimumLogLevel": "Information",
    "Performance": {
      "LogOnlySlowMethods": true,
      "SlowMethodThresholdMs": 1000
    }
  }
}
Troubleshooting
Nothing is Being Logged
Check these common issues:
- Service registration missing: - // Make sure you have this services.AddActivityLogging(); services.AddActivityLoggedService<IYourService, YourService>();
- Logging is disabled: - { "ActivityLogging": { "IsEnabled": true // Make sure this is true } }
- Log level too high: - { "ActivityLogging": { "MinimumLogLevel": "Debug" // Try lowering this } }
Performance Issues
If logging is slowing down your app:
- Enable async logging: - { "ActivityLogging": { "AsyncLogging": { "EnableAsyncLogging": true } } }
- Log only slow methods: - { "ActivityLogging": { "Performance": { "LogOnlySlowMethods": true, "SlowMethodThresholdMs": 1000 } } }
- Reduce serialization: - { "ActivityLogging": { "Serialization": { "MaxDepth": 1, "SerializeInputParameters": false, "SerializeReturnValues": false } } }
Serialization Errors
If you get serialization exceptions:
- Exclude problematic types: - { "ActivityLogging": { "Serialization": { "ExcludedTypes": [ "System.IO.Stream", "Microsoft.AspNetCore.Http.HttpContext", "YourApp.ProblematicType" ] } } }
- Exclude sensitive properties: - { "ActivityLogging": { "Serialization": { "ExcludedProperties": ["Password", "Secret", "InternalData"] } } }
Database Connection Issues
If logs aren't being saved to the database:
- Check connection string: - services.AddActivityLogging() .WithStorage() .UseSqlServer("your-connection-string-here");
- Run database migrations: - dotnet ef database update
- Test with in-memory database first: - services.AddActivityLogging() .WithStorage() .UseInMemoryDatabase("TestDb");
Getting Help
Enable debug logging to see what's happening:
{
  "Logging": {
    "LogLevel": {
      "ActivityLog": "Debug"
    }
  }
}
This will show detailed information about what the activity logging system is doing, helping you identify any issues.
Support
For questions and support:
- Check the troubleshooting section above
- Review the configuration examples
- Enable debug logging to see detailed information
- Visit our GitHub repository for issues and discussions
| Product | Versions Compatible and additional computed target framework versions. | 
|---|---|
| .NET | 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. | 
- 
                                                    net9.0- Castle.Core (>= 5.2.1)
- DotNetBrightener.DataAccess.Abstractions (>= 2025.0.9)
- DotNetBrightener.DataAccess.Abstractions.Models (>= 2025.0.9)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.10)
- Microsoft.Extensions.Options (>= 9.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.10)
- System.Text.Json (>= 9.0.10)
- VampireCoder.SharedUtils (>= 2025.0.9)
 
NuGet packages (1)
Showing the top 1 NuGet packages that depend on DotNetBrightener.ActivityLog:
| Package | Downloads | 
|---|---|
| DotNetBrightener.ActivityLog.DataStorage Package Description | 
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | 
|---|---|---|
| 2025.0.10-preview-559 | 45 | 10/29/2025 | 
| 2025.0.10-preview-557 | 111 | 10/27/2025 | 
| 2025.0.9 | 127 | 10/26/2025 | 
| 2025.0.9-preview-553 | 117 | 10/26/2025 | 
| 2025.0.9-preview-539 | 140 | 10/12/2025 | 
| 2025.0.9-preview-535 | 185 | 10/8/2025 | 
| 2025.0.9-preview-509 | 208 | 10/2/2025 | 
| 2025.0.9-preview-508 | 189 | 10/2/2025 | 
| 2025.0.9-preview-487 | 203 | 9/29/2025 | 
| 2025.0.9-preview-481 | 188 | 9/29/2025 | 
| 2025.0.9-preview-473 | 173 | 9/28/2025 | 
| 2025.0.8 | 211 | 9/23/2025 | 
| 2025.0.6 | 210 | 9/22/2025 | 
| 2025.0.6-preview-455 | 209 | 9/22/2025 | 
| 2025.0.6-preview-454 | 330 | 9/17/2025 | 
| 2025.0.6-preview-441 | 160 | 9/14/2025 | 
| 2025.0.6-preview-440 | 166 | 9/14/2025 | 
| 2025.0.6-preview-406 | 215 | 9/2/2025 | 
| 2025.0.6-preview-401 | 197 | 9/2/2025 | 
| 2025.0.6-preview-400 | 185 | 9/2/2025 |