AuditLogLens 0.2.0-alpha.2
dotnet add package AuditLogLens --version 0.2.0-alpha.2
NuGet\Install-Package AuditLogLens -Version 0.2.0-alpha.2
<PackageReference Include="AuditLogLens" Version="0.2.0-alpha.2" />
<PackageVersion Include="AuditLogLens" Version="0.2.0-alpha.2" />
<PackageReference Include="AuditLogLens" />
paket add AuditLogLens --version 0.2.0-alpha.2
#r "nuget: AuditLogLens, 0.2.0-alpha.2"
#:package AuditLogLens@0.2.0-alpha.2
#addin nuget:?package=AuditLogLens&version=0.2.0-alpha.2&prerelease
#tool nuget:?package=AuditLogLens&version=0.2.0-alpha.2&prerelease
AuditLogLens
AuditLogLens helps EF Core applications write audit logs that people can actually read.
Raw ChangeTracker data is often full of ids, technical fields, and noisy changes. AuditLogLens captures those changes automatically, keeps auditing opt-in through explicit rules, and gives you a structured enrichment pipeline to turn raw values into meaningful audit records. It batches related data before enrichment runs, so readable logs do not require a pile of per-row lookup queries.
It watches SaveChanges, creates AuditChange objects, enriches them with readable data, maps them to an audit entity, and writes audit records through EF Core. Applications can also create manual AuditChange objects and send them through the same enrichment and writing pipeline.
The main idea is simple:
EF Core changes or manual events -> AuditChange -> enrichment -> mapper -> audit table
Installation
dotnet add package AuditLogLens --version 0.2.0-alpha.1
0.2.0-alpha.1 is an alpha release. The API is usable, but still being shaped before a stable 1.0 release.
Quick Start
1. Register AuditLogLens
services
.AddAuditInfrastructure()
.AddAuditRestrictions<ApplicationAuditRestrictions>()
.AddAuditEnricher<AuditMetadataEnricher>();
This uses the built-in AuditLogLensEntry audit entity and the built-in mapper.
AddAuditRestrictions<T>() tells AuditLogLens which entities and properties should be audited.
2. Add the EF Core interceptor
services.AddDbContext<AppDbContext>((provider, options) =>
{
options
.UseNpgsql(connectionString)
.AddAuditInterceptor(provider);
});
3. Add the default audit entity to your EF model
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.UseAuditLogLens();
}
The default entity is AuditLogLensEntry. It stores:
IdCreatedAtUtcTableNameStateOldValuesJsonNewValuesJson
UseAuditLogLens() is defined in AuditLogLensModelBuilderExtensions.
The default mapper is DefaultAuditLogLensEntryMapper. Use AddEfAuditWriter<TAuditEntry, TMapper>() only when you want your own audit table shape.
4. Optional: map AuditChange to your own audit entity
public sealed class AuditRecordMapper : IAuditEntryMapper<AuditRecord>
{
public bool CanMap(DbContext dbContext) => dbContext is AppDbContext;
public AuditRecord? Map(AuditChange change, DbContext dbContext)
{
return new AuditRecord
{
TableName = change.TableName,
EntityId = change.EntityId?.ToString(),
State = change.State.ToString(),
OldValues = JsonSerializer.Serialize(change.OldValues),
NewValues = JsonSerializer.Serialize(change.NewValues)
};
}
}
Register the custom writer instead of the default writer:
services
.AddAuditInfrastructure()
.AddEfAuditWriter<AuditRecord, AuditRecordMapper>()
.AddAuditRestrictions<ApplicationAuditRestrictions>();
5. Configure restrictions
using AuditLogLens.Restrictions;
public sealed class ApplicationAuditRestrictions : AuditRestrictionsBase
{
protected override void Configure(AuditRestrictionRules rules)
{
rules.For<Patient>()
.Ignore(x => x.InternalNote);
rules.For<Visit>();
}
}
If no rules are configured, nothing is audited. This is intentional: audit logging should be explicit, so an application does not accidentally write sensitive tables.
If at least one rule is configured, only listed entities are audited.
6. Add readable enrichment
Domain-level enrichment is the most common way to replace raw ids with readable values.
using AuditLogLens.Enrichment;
public sealed class Visit : IHasAuditEnrichmentConfig<Visit>
{
public int DoctorId { get; set; }
public static void ConfigureAuditEnrichment(IAuditEnrichmentPlanBuilder builder)
{
builder.Reference<Visit, Doctor, int>(
x => x.DoctorId,
"DoctorName",
doctor => doctor.FullName);
}
}
This can turn audit data like:
DoctorId = 42
into:
DoctorName = "Dr. Smith"
AuditLogLens batches enrichment loads across all changes first. This helps avoid the common N+1 shape when many audit records need the same related data.
For complex enrichers, use Lookup(...) in Configure(...) to preload data in the same batch pipeline, then read it from context.GetLoaded<T>(...) inside a hook. This is useful for JSON/custom values where a simple Reference(...) is not enough.
Application-level enrichers can also add metadata or reshape values through AuditEntityEnricherBase. It uses template-method hooks around the single bag merge:
BeforeMergeAsync
BeforeMergeChangeAsync
merge bags into AuditChange
AfterMergeChangeAsync
AfterMergeAsync
Use per-change hooks for simple one-change logic. Use whole-context hooks when you need grouping, cross-change correlation, or application services.
Documentation
Start here:
- Getting Started
- Documentation Index
- Changelog
- Recipes
- Enrichment
- Manual Audit
- Restrictions
- Writing Audit Records
- Transactions
- Testing
- Architecture
Main Concepts
AuditChangeis the library-level representation of one audited change.IAuditChangeFactorycreates explicit manual audit changes.IAuditPipelineruns enrichment and writing for already-created changes.AuditLogLensEntryis the built-in audit entity for fast setup.IAuditEntryMapper<TAuditEntry>mapsAuditChangeto your custom audit entity.AuditRestrictionsBasecontrols which entities and properties are audited.IHasAuditEnrichmentConfig<TSelf>adds declarative enrichment rules near the domain entity.AuditEntityEnricherBaseis the base class for application-level enrichment that does not belong to one domain entity.
Project
Current Status
AuditLogLens is available as a public alpha NuGet package.
The current package has:
- EF Core
SaveChangesInterceptorintegration. - Added, modified, and deleted entity detection.
- Added-entity temporary key handling.
- Declarative enrichment with batched reference loading.
- Collection enrichment for explicit join entities.
- Custom application enrichers.
- Public manual audit pipeline for application-created events.
- Default EF writer with recursion suppression.
- Optional transactional audit writing.
License
AuditLogLens is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.1)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.1)
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 |
|---|---|---|
| 0.2.0-alpha.2 | 360 | 6/9/2026 |
| 0.2.0-alpha.1 | 136 | 6/1/2026 |
| 0.1.0-alpha.1 | 373 | 5/22/2026 |