abp框架扩展AbpAuditLogs审计日志
ABP框架默认提供审计日志功能,只需实现并重写IAuditingStore接口即可
1.创建自定义审计日志的model,可以自定义字段内容以及字段类型
public class AuditLog : AuditedEntity{ /// /// Maximum length of public const int MaxServiceNameLength = 256; ///property. /// /// Maximum length of public const int MaxMethodNameLength = 256; ///property. /// /// Maximum length of public const int MaxParametersLength = 1024; ///property. /// /// Maximum length of public const int MaxReturnValueLength = 1024; ///property. /// /// Maximum length of public const int MaxClientIpAddressLength = 64; ///property. /// /// Maximum length of public const int MaxClientNameLength = 128; ///property. /// /// Maximum length of public const int MaxBrowserInfoLength = 512; ///property. /// /// Maximum length of public const int MaxExceptionLength = 2048; ///property. /// /// Maximum length of public const int MaxCustomDataLength = 2048; ///property. /// /// Service (class/interface) name. /// [StringLength(MaxServiceNameLength)] public virtual string ServiceName { get; set; } ////// Executed method name. /// [StringLength(MaxMethodNameLength)] public virtual string MethodName { get; set; } ////// Calling parameters. /// [StringLength(MaxParametersLength)] public virtual string Parameters { get; set; } ////// Return values. /// [StringLength(MaxReturnValueLength)] public virtual string ReturnValue { get; set; } ////// Start time of the method execution. /// public virtual DateTime ExecutionTime { get; set; } ////// Total duration of the method call as milliseconds. /// public virtual int ExecutionDuration { get; set; } ////// IP address of the client. /// [StringLength(MaxClientIpAddressLength)] public virtual string ClientIpAddress { get; set; } ////// Name (generally computer name) of the client. /// [StringLength(MaxClientNameLength)] public virtual string ClientName { get; set; } ////// Browser information if this method is called in a web request. /// [StringLength(MaxBrowserInfoLength)] public virtual string BrowserInfo { get; set; } ////// Exception object, if an exception occured during execution of the method. /// [StringLength(MaxExceptionLength)] public virtual string Exception { get; set; } ////// [StringLength(MaxCustomDataLength)] public virtual string CustomData { get; set; } ///. /// /// Creates a new CreateFromAuditInfo from given /// Source. /// object /// Source object /// The public static AuditLog CreateFromAuditInfo(AuditInfo auditInfo) { var exceptionMessage = GetAbpClearException(auditInfo.Exception); return new AuditLog { ServiceName = auditInfo.ServiceName.TruncateWithPostfix(MaxServiceNameLength), MethodName = auditInfo.MethodName.TruncateWithPostfix(MaxMethodNameLength), Parameters = auditInfo.Parameters.TruncateWithPostfix(MaxParametersLength), ReturnValue = auditInfo.ReturnValue.TruncateWithPostfix(MaxReturnValueLength), ExecutionTime = auditInfo.ExecutionTime, ExecutionDuration = auditInfo.ExecutionDuration, ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(MaxClientIpAddressLength), ClientName = auditInfo.ClientName.TruncateWithPostfix(MaxClientNameLength), BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(MaxBrowserInfoLength), Exception = exceptionMessage.TruncateWithPostfix(MaxExceptionLength), CustomData = auditInfo.CustomData.TruncateWithPostfix(MaxCustomDataLength) }; } public static string GetAbpClearException(Exception exception) { var clearMessage = ""; switch (exception) { case null: return null; case AbpValidationException abpValidationException: clearMessage = "There are " + abpValidationException.ValidationErrors.Count + " validation errors:"; foreach (var validationResult in abpValidationException.ValidationErrors) { var memberNames = ""; if (validationResult.MemberNames != null && validationResult.MemberNames.Any()) { memberNames = " (" + string.Join(", ", validationResult.MemberNames) + ")"; } clearMessage += "\r\n" + validationResult.ErrorMessage + memberNames; } break; case UserFriendlyException userFriendlyException: clearMessage = $"UserFriendlyException.Code:{userFriendlyException.Code}\r\nUserFriendlyException.Details:{userFriendlyException.Details}"; break; } return exception + (clearMessage.IsNullOrWhiteSpace() ? "" : "\r\n\r\n" + clearMessage); } }object that is created using
2.在对应的DBContext中添加对应的model 并生成迁移文件,完成迁移
public virtual DbSetAuditLog { get; set; }
Add-Migration test
Update-Database
3.自定义AuditStore实现Abp的IAuditingStore,重写对应方法
public class AuditingStoreTest : IAuditingStore, ITransientDependency
{
private readonly IRepository _auditLogRepository;
///
/// Creates a new .
///
public AuditingStoreTest(IRepository auditLogRepository)
{
_auditLogRepository = auditLogRepository;
}
public virtual Task SaveAsync(AuditInfo auditInfo)
{
return _auditLogRepository.InsertAsync(AuditLog.CreateFromAuditInfo(auditInfo));
}
public virtual void Save(AuditInfo auditInfo)
{
_auditLogRepository.Insert(AuditLog.CreateFromAuditInfo(auditInfo));
}
}
4.找一个实现AbpModule模块的类中将原有的审计日志替换为自定义的
Configuration.ReplaceService(typeof(IAuditingStore), () =>
{
IocManager.IocContainer.Register(
Component.For()
.ImplementedBy()
.LifestyleTransient()
);
});
根据以上四步即可完成对abp审计日志的自定义扩展