Eniks.AuditTrails
1.0.0
dotnet add package Eniks.AuditTrails --version 1.0.0
NuGet\Install-Package Eniks.AuditTrails -Version 1.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="Eniks.AuditTrails" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Eniks.AuditTrails" Version="1.0.0" />
<PackageReference Include="Eniks.AuditTrails" />
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 Eniks.AuditTrails --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Eniks.AuditTrails, 1.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 Eniks.AuditTrails@1.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=Eniks.AuditTrails&version=1.0.0
#tool nuget:?package=Eniks.AuditTrails&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
AuditTrails
A simple audit trail library for .NET with FluentResults integration. Creates audit entries that you save to your own database.
Features
- ✨ Simple - Just creates audit entries, you handle storage
- 📝 Comprehensive - Track all CRUD operations
- 🔄 Change Tracking - Capture before/after values
- ✅ FluentResults - Built-in result-based error handling
- 🎯 DI Ready - Native ASP.NET Core support
Installation
dotnet add package Eniks.AuditTrails
Quick Start
1. Register Service
using AuditTrails.Extensions;
builder.Services.AddAuditTrails();
2. Implement IAuditService (Your Storage Logic)
using AuditTrails.Interfaces;
using AuditTrails.Models;
using FluentResults;
public class MyAuditService : IAuditService
{
private readonly AppDbContext _db;
public MyAuditService(AppDbContext db)
{
_db = db;
}
public async Task<Result> SaveAuditEntryAsync(AuditEntry entry, CancellationToken cancellationToken = default)
{
try
{
_db.AuditEntries.Add(entry);
await _db.SaveChangesAsync(cancellationToken);
return Result.Ok();
}
catch (Exception ex)
{
return Result.Fail($"Failed to save audit: {ex.Message}");
}
}
}
// Register your service
builder.Services.AddScoped<IAuditService, MyAuditService>();
3. Use It
public class UserService
{
private readonly IAuditLogger _auditLogger;
private readonly IAuditService _auditService;
public UserService(IAuditLogger auditLogger, IAuditService auditService)
{
_auditLogger = auditLogger;
_auditService = auditService;
}
public async Task<Result> CreateUserAsync(User user)
{
// ... create user ...
// Create audit entry
var auditResult = _auditLogger.CreateEntityAuditEntry(
AuditOperation.Create,
"User",
user.Id,
$"Created user {user.Email}",
userId: currentUserId
);
if (auditResult.IsSuccess)
{
// Save to your database
await _auditService.SaveAuditEntryAsync(auditResult.Value);
}
return Result.Ok();
}
}
Usage Examples
Simple Audit
var result = _auditLogger.CreateAuditEntry(
AuditOperation.Login,
"User logged in successfully",
userId: "user123"
);
if (result.IsSuccess)
{
await _auditService.SaveAuditEntryAsync(result.Value);
}
Entity Operations
var result = _auditLogger.CreateEntityAuditEntry(
AuditOperation.Update,
entityType: "Product",
entityId: "prod-456",
description: "Updated product price",
userId: currentUserId
);
if (result.IsSuccess)
{
await _auditService.SaveAuditEntryAsync(result.Value);
}
Change Tracking
var oldProduct = new { Name = "Widget", Price = 10.00 };
var newProduct = new { Name = "Widget", Price = 15.00 };
var result = _auditLogger.CreateChangeAuditEntry(
AuditOperation.Update,
"Product",
productId,
oldValues: oldProduct,
newValues: newProduct,
userId: currentUserId
);
if (result.IsSuccess)
{
await _auditService.SaveAuditEntryAsync(result.Value);
}
Error Logging
try
{
await PerformOperationAsync();
}
catch (Exception ex)
{
var result = _auditLogger.CreateErrorAuditEntry(
AuditOperation.Update,
"Failed to update profile",
ex,
userId: currentUserId
);
if (result.IsSuccess)
{
await _auditService.SaveAuditEntryAsync(result.Value);
}
}
Configuration
builder.Services.AddAuditTrails(options =>
{
options.IncludeStackTrace = false; // Include full stack trace (default: false)
options.MaxDescriptionLength = 2000; // Max description length (default: 2000)
});
AuditEntry Model
public class AuditEntry
{
public string Id { get; set; } // Auto-generated GUID
public DateTime Timestamp { get; set; } // Auto-set to UTC now
public AuditOperation Operation { get; set; } // Type of operation
public AuditSeverity Severity { get; set; } // Auto-set based on operation
public string? EntityType { get; set; } // e.g., "User", "Product"
public string? EntityId { get; set; } // Entity identifier
public string? UserId { get; set; } // Who performed the action
public string? Name { get; set; } // User's name
public string Description { get; set; } // What happened
public string? OldValues { get; set; } // Before (JSON)
public string? NewValues { get; set; } // After (JSON)
public Dictionary<string, string>? Metadata { get; set; } // Extra data
public string? ExceptionDetails { get; set; } // Error info
public bool Success { get; set; } // Was it successful
}
Operations
public enum AuditOperation
{
Create, Read, Update, Delete,
Login, Logout, AccessDenied,
Export, Import, ConfigurationChange, Custom
}
Severity Levels
public enum AuditSeverity
{
Information, // Normal operations
Warning, // Potentially problematic
Error, // Failed operations
Critical, // Severe issues
Success // Explicitly successful
}
Database Setup Example
Entity Framework Core
public class AppDbContext : DbContext
{
public DbSet<AuditEntry> AuditEntries { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AuditEntry>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Description).HasMaxLength(2000);
entity.HasIndex(e => e.Timestamp);
entity.HasIndex(e => e.UserId);
entity.HasIndex(e => e.EntityType);
});
}
}
Querying Your Audit Logs
// You handle all queries in your application
public async Task<List<AuditEntry>> GetUserActivityAsync(string userId, int days = 7)
{
return await _db.AuditEntries
.Where(a => a.UserId == userId)
.Where(a => a.Timestamp >= DateTime.UtcNow.AddDays(-days))
.OrderByDescending(a => a.Timestamp)
.Take(50)
.ToListAsync();
}
public async Task<List<AuditEntry>> GetEntityHistoryAsync(string entityType, string entityId)
{
return await _db.AuditEntries
.Where(a => a.EntityType == entityType && a.EntityId == entityId)
.OrderByDescending(a => a.Timestamp)
.ToListAsync();
}
Why This Approach?
- Your Database, Your Rules - Store audit logs however you want
- Simple - No complex abstractions
- Flexible - Query and filter your way
- Portable - Works with any data store
License
MIT License - Free for commercial and personal use
Support
For issues or questions, please open an issue on GitHub.
| 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net9.0
- FluentResults (>= 3.16.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.0)
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 |
|---|---|---|
| 1.0.0 | 157 | 2/14/2026 |
Initial release of AuditTrails library with support for comprehensive audit logging and multiple storage backends.