| name | abp-audit-logging |
| description | ABP Framework v10.x (10.4/10.5) audit logging: AbpAuditingOptions, entity history, IAuditingStore, audit log storage and filtering. Use when configuring audit trails, audit logs, or entity history in ABP. |
ABP Audit Logging Skill
Trigger
User asks about audit logging, audit trails, entity history, AbpAuditingOptions, IAuditingStore, audit log contributors, or tracking changes in ABP Framework.
Core Concepts
ABP's audit logging system:
- Automatically logs application service method calls
- Tracks entity changes (create, update, delete) when configured
- Records HTTP request details, parameters, execution time, exceptions
- Stores audit logs in database via
IAuditingStore
- Extensible via contributors and options
Configuration
AbpAuditingOptions
Configure<AbpAuditingOptions>(options =>
{
options.IsEnabled = true;
options.HideErrors = true;
options.IsEnabledForAnonymousUsers = true;
options.AlwaysLogOnException = true;
options.IsEnabledForIntegrationService = false;
options.IsEnabledForGetRequests = false;
options.DisableLogActionInfo = false;
options.ApplicationName = "MyApp";
options.SaveEntityHistoryWhenNavigationChanges = true;
});
Key options:
IsEnabled — Master switch; if false, all other options ignored
HideErrors — If true, audit save errors logged silently; if false, throws
AlwaysLogOnException — Force audit log on exception regardless of other settings
IsEnabledForGetRequests — GET requests normally not logged (shouldn't change data)
ApplicationName — Critical when multiple apps share audit log database
Entity History
Enabling Entity History
Important: Entity history is disabled by default for all entities. You must explicitly enable it.
Enable for All Entities
Configure<AbpAuditingOptions>(options =>
{
options.EntityHistorySelectors.AddAllEntities();
});
Enable with Custom Selector
Configure<AbpAuditingOptions>(options =>
{
options.EntityHistorySelectors.Add(
new NamedTypeSelector(
"MySelectorName",
type => typeof(IEntity).IsAssignableFrom(type)
)
);
});
Enable per Entity with Attribute
[Audited]
public class MyEntity : Entity<Guid>
{
}
Disable per Entity
[DisableAuditing]
public class MyEntity : Entity<Guid>
{
}
Disable Specific Properties
[Audited]
public class MyUser : Entity<Guid>
{
public string Name { get; set; }
[DisableAuditing]
public string Password { get; set; }
}
Enable Only Specific Properties
[DisableAuditing]
public class MyUser : Entity<Guid>
{
[Audited]
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Ignore Update Audit Properties
entity.IgnoreAuditPropertiesOnUpdate();
Entity Rules
An entity is ignored in entity change audit logging if:
- Added to
AbpAuditingOptions.IgnoredTypes
- Does not implement
IEntity
- Entity type is not public
Enabling/Disabling Audit Logging
Controllers & Actions
[DisableAuditing]
public class MyController : AbpController
{
[DisableAuditing]
public IActionResult MyAction() { }
}
Application Services & Methods
[DisableAuditing]
public class MyAppService : ApplicationService
{
[DisableAuditing]
public async Task DoSomethingAsync() { }
}
Other Services
[Audited]
public class MyService : ITransientDependency
{
public virtual async Task DoWorkAsync() { }
}
Service must be DI-registered and method must be virtual for interception.
IAuditingStore
Default implementation saves to database. Custom implementation:
public class MyAuditingStore : IAuditingStore, ITransientDependency
{
public async Task SaveAsync(AuditLogInfo auditInfo)
{
}
}
Audit Log Object
public class AuditLogInfo
{
public string ApplicationName { get; set; }
public Guid? UserId { get; set; }
public string UserName { get; set; }
public Guid? TenantId { get; set; }
public string TenantName { get; set; }
public string ImpersonatorUserName { get; set; }
public Guid? ImpersonatorUserId { get; set; }
public DateTime ExecutionTime { get; set; }
public int ExecutionDuration { get; set; }
public string ClientIpAddress { get; set; }
public string ClientName { get; set; }
public string BrowserInfo { get; set; }
public string HttpMethod { get; set; }
public string Url { get; set; }
public int? HttpStatusCode { get; set; }
public string ExceptionMessage { get; set; }
public string Exception { get; set; }
public Dictionary<string, object> ExtraProperties { get; set; }
public List<AuditLogActionInfo> Actions { get; set; }
public List<EntityChangeInfo> EntityChanges { get; set; }
public List<EntityPropertyChangeInfo> EntityPropertyChanges { get; set; }
}
Audit Log Contributors
Extend audit log with custom data:
public class MyAuditLogContributor : AuditLogContributor
{
public override Task PreContributeAsync(AuditLogContributionContext context)
{
context.AuditLog.ExtraProperties["CustomKey"] = "CustomValue";
return Task.CompletedTask;
}
public override Task PostContributeAsync(AuditLogContributionContext context)
{
return Task.CompletedTask;
}
}
Configure<AbpAuditingOptions>(options =>
{
options.Contributors.Add<MyAuditLogContributor>();
});
AlwaysLog Selectors
Force audit logging for specific services regardless of other settings:
Configure<AbpAuditingOptions>(options =>
{
options.AlwaysLogSelectors.Add(
new NamedTypeSelector(
"CriticalServices",
type => typeof(ICriticalService).IsAssignableFrom(type)
)
);
});
Database Provider Support
Audit logging module supports:
- Entity Framework Core —
AbpAuditLoggingDbContext
- MongoDB —
AbpAuditLoggingMongoDbContext
Both providers store audit logs in AbpAuditLogs collection/table.
UseAuditing()
Enable ASP.NET Core auditing middleware:
app.UseAuditing();
Usually called automatically by AbpAspNetCoreAuditingModule.
AbpAspNetCoreAuditingOptions
ASP.NET Core specific auditing options:
Configure<AbpAspNetCoreAuditingOptions>(options =>
{
options.UrlControllers.Add("HealthCheck");
});
Configure<AbpAspNetCoreAuditingUrlOptions>(options =>
{
options.IgnoredUrls.Add("/health");
options.IgnoredUrls.Add("/api/health");
});
Blazor Server Limitation
Entity history in Blazor Server: Not guaranteed to be complete for every UI interaction. Blazor Server uses SignalR-based event handling, and under some flows the audit scope/action tracking may not align with DbContext.SaveChanges, causing missing or partial entity change records. See GitHub #11682.
Best Practices
- Enable entity history explicitly — it's off by default
- Use
AddAllEntities() only if you need full audit trail (storage intensive)
- Use
[Audited] / [DisableAuditing] for fine-grained control
- Disable auditing on sensitive properties (passwords, tokens, PII)
- Set
ApplicationName when multiple apps share audit database
- Use contributors to add custom context (correlation IDs, session data)
- Don't log GET requests unless debugging (they shouldn't change data)
- Monitor audit log storage — it grows fast with entity history enabled
- Use
AlwaysLogSelectors for critical services that must always be logged
- Test Blazor Server entity history — known limitations exist
Audit Logging Module
The Volo.Abp.SettingManagement module includes IAuditingStore implementation:
- Persists audit logs to database
- Provides EF Core and MongoDB providers
- Includes domain layer (aggregates, repositories)
Installation
abp add-package Volo.Abp.AuditLogging.EntityFrameworkCore
Related