[Abp 源码分析]十五、自动审计记录 (4)

其实在这一串 if 当中,你可以发现有一句代码对方法是否标注了 DisableAuditingAttribute 特性进行了判断,如果标注了该特性,则不为该方法创建审计信息。所以我们就可以通过该特性来控制自己应用服务类,控制里面的的接口是否要创建审计信息。同理,我们也可以通过显式标注 AuditedAttribute 特性来让拦截器为这个方法创建审计信息。

public bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false) { if (!_configuration.IsEnabled) { return false; } if (!_configuration.IsEnabledForAnonymousUsers && (AbpSession?.UserId == null)) { return false; } if (methodInfo == null) { return false; } if (!methodInfo.IsPublic) { return false; } if (methodInfo.IsDefined(typeof(AuditedAttribute), true)) { return true; } if (methodInfo.IsDefined(typeof(DisableAuditingAttribute), true)) { return false; } var classType = methodInfo.DeclaringType; if (classType != null) { if (classType.GetTypeInfo().IsDefined(typeof(AuditedAttribute), true)) { return true; } if (classType.GetTypeInfo().IsDefined(typeof(DisableAuditingAttribute), true)) { return false; } if (_configuration.Selectors.Any(selector => selector.Predicate(classType))) { return true; } } return defaultValue; } 2.3.2 创建审计信息

审计信息在创建的时候,就为我们将当前调用接口时的用户信息存放在了审计信息当中,之后通过 IAuditInfoProvider 的 Fill() 方法填充了客户端 IP 与浏览器信息。

public AuditInfo CreateAuditInfo(Type type, MethodInfo method, IDictionary<string, object> arguments) { // 构建一个审计信息对象 var auditInfo = new AuditInfo { TenantId = AbpSession.TenantId, UserId = AbpSession.UserId, ImpersonatorUserId = AbpSession.ImpersonatorUserId, ImpersonatorTenantId = AbpSession.ImpersonatorTenantId, ServiceName = type != null ? type.FullName : "", MethodName = method.Name, // 将参数转换为 JSON 字符串 Parameters = ConvertArgumentsToJson(arguments), ExecutionTime = Clock.Now }; try { // 填充客户 IP 与浏览器信息等 _auditInfoProvider.Fill(auditInfo); } catch (Exception ex) { Logger.Warn(ex.ToString(), ex); } return auditInfo; } 2.4 审计信息持久化

通过上一小节我们知道了在调用审计信息保存接口的时候,实际上是调用的 IAuditingStore 所提供的 SaveAsync(AuditInfo auditInfo) 方法来持久化这些审计日志信息的。

如果你没有集成 Abp.Zero 项目的话,则使用的是默认的实现,就是简单通过 ILogger 输出审计信息到日志当中。

[Abp 源码分析]十五、自动审计记录

默认有这两种实现,至于第一种是 Abp 的单元测试项目所使用的。

这里我们就简单将一下 AuditingStore 这个实现吧,其实很简单的,就是注入了一个仓储,在保存的时候往审计日志表插入一条数据即可。

这里使用了 AuditLog.CreateFromAuditInfo() 方法将 AuditInfo 类型的审计信息转换为数据库实体,用于仓储进行插入操作。

public class AuditingStore : IAuditingStore, ITransientDependency { private readonly IRepository<AuditLog, long> _auditLogRepository; public AuditingStore(IRepository<AuditLog, long> auditLogRepository) { _auditLogRepository = auditLogRepository; } public virtual Task SaveAsync(AuditInfo auditInfo) { // 向表中插入数据 return _auditLogRepository.InsertAsync(AuditLog.CreateFromAuditInfo(auditInfo)); } } 3. 后记

前几天发现 Abp 的团队有开了一个新坑,叫做 Abp vNext 框架,该框架全部基于 .NET Core 进行开发,而且会针对微服务项目进行专门的设计,有兴趣的朋友可以持续关注。

其 GitHub 地址为:https://github.com/abpframework/abp/

官方地址为:https://abp.io/

4.点此跳转到总目录

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppgsg.html