Audit.NET
用法|输出|自定义|数据提供商|创建策略|配置|扩展
| 问题 | 建立状态 | 优质门 | 捐赠 |
|---|---|---|---|
一个可扩展的框架,用于审核.NET和.NET Core中执行操作。
生成审计日志,并有证据表明重建和检查影响特定操作或程序的活动。
使用Audit.NET ,您可以生成详细的跟踪信息,以进行执行操作。它捕获了环境数据,例如呼叫者的用户ID,机器名称,方法名称,异常和执行时间。该框架还提供了一种可扩展的机制来丰富日志和管理审计输出。
-
提供了审核的交互扩展,提供了不同的系统,例如实体框架,MVC,WebAPI,WCF,文件系统,SignalR,Mongoclient和HTTPClient。
-
Output extensions are provided to log to JSON Files, Event Log, Open Telemetry Spans, SQL, MySQL, PostgreSQL, RavenDB, MongoDB, AzureBlob, AzureTables, AzureCosmos, AzureEventHubs, Redis, Elasticsearch, OpenSearch, DynamoDB, ImmuDB, UDP datagrams, Channels and more.
-
包括输出包装器,以促进其他数据提供商的封装,例如弹性或懒惰的实例化,例如Polly,Lazy,Lazy,Teferred and Riscoral。
nuget
要安装软件包在软件包管理器控制台上运行以下命令:
PM> Install-Package Audit.NET
ChangElog
检查ChangElog.md文件。
ZZZ项目 – 赞助
实体框架扩展名和Dapper Plus是主要赞助商,并为Audit.NET的开发做出贡献而感到自豪
将审核的力量与批量操作的速度相结合,以获得两全其美的最佳 – 审计和表现。
介绍
审核范围和审核事件是此框架的中心对象。
审计范围
审核尺寸是此框架中的中心对象,代表了经审核操作或事件的范围。它充当审核的背景,捕获相关细节,例如开始时间,涉及实体以及任何其他自定义信息。本质上,审计范围封装了审核证件,控制其生命周期。
审核科普是一个可支配对象,通常在使用语句中使用,以确保在退出范围后正确完成审计信息。
请参阅审核范围Statechart。
审核事件
审核Vent的功能充当可扩展的信息容器,可捕获审计操作的详细信息,是审计范围内审核信息的表示。它包括有关审核操作的详细信息,例如事件类型,时间戳,执行持续时间以及任何自定义字段或属性。
审核驱动器通常被序列化为适合存储或传输的格式,例如JSON。
审核事件是使用数据提供商存储的。您可以使用可用的数据提供商之一或实施自己的。
审核范围工厂
创建审核范围的首选方法是使用iauditsCopeFactory实例。此方法可确保所有审核范围的集中式配置。
var factory = new AuditScopeFactory ( ) ; using var scope = factory . Create ( new AuditScopeOptions ( .. . ) ) ; .. .
如果您使用的是DI容器,则可以注册IauditScopeFactory作为服务,并将其注入您的类。 IauditsCopeFactory的默认实现由AuditsCopeFactory类提供。
services . AddScoped < IAuditScopeFactory , AuditScopeFactory > ( ) ;
然后,您可以将IauditsCopeFactory注入类,以创建审核范围:
public class MyService { private readonly IAuditScopeFactory _auditScopeFactory ; public MyService ( IAuditScopeFactory auditScopeFactory ) { _auditScopeFactory = auditScopeFactory ; } public void MyMethod ( ) { using var scope = _auditScopeFactory . Create ( new AuditScopeOptions ( .. . ) ) ; .. . } }
您还可以实现自己的IauditScopeFactory来自定义审核范围的创建。推荐的方法是从AuctitScopeFactory类中继承。通过覆盖启用和划分的方法,您可以在创建之前配置审核范围选项,并分别在创建后自定义审计范围。
例如:
public class MyAuditScopeFactory : AuditScopeFactory { private readonly IMyService _myService ; public MyAuditScopeFactory ( IMyService myService ) { _myService = myService ; } public override void OnConfiguring ( AuditScopeOptions options ) { // Set the data provider to use options . DataProvider = new SqlDataProvider ( .. . ) ; } public override void OnScopeCreated ( AuditScope auditScope ) { // Add a custom field to the audit scope auditScope . SetCustomField ( \"CustomId\" , _myService . GetId ( ) ) ; } }
生成审计事件的几项扩展,例如audit.entityframework.core,audit.webapi.core,audit.mvc.core和audit.signalr,将自动尝试解决来自服务提供商的IauditsCopeFactory和AuditDataProvider Instances。
支持较旧的.NET框架
从版本23.0.0开始,该库及其扩展程序停止了对较旧的.NET框架和实体框架(在2023年之前丢失Microsoft支持的版本)的支持。
作为参考,请咨询以下链接:
- .NET核心支持政策
- 实体框架核心版本
该库及其扩展程序将维持对以下最低.NET框架版本的支持:
- .NET框架4.6.2(Net462)
- .NET标准2.0(NetStandard2.0)
- .NET 6(NET6.0)
用法
审核范围是该框架的中心对象。它封装了审计事件,控制了其生命周期。审核事件是审核操作的可扩展信息容器。
有几种创建审计范围的方法:
-
调用auctitscopeFactory实例的create() / createAsync()方法。这是推荐的方法。例如:
var scope = auditScopeFactory . Create ( new AuditScopeOptions ( .. . ) ) ;
-
例如,在审核尺寸上使用静态方法的过载create() / createasync(),例如:
var scope = AuditScope . Create ( new AuditScopeOptions ( ) { EventType = \"Order:Update\" , TargetGetter = ( ) => order , ExtraFields = new { MyProperty = \"value\" } } ) ;
-
使用提供的流利API,例如:
var scope = AuditScope . Create ( _ => _ . EventType ( \"Order:Update\" ) . ExtraFields ( new { MyProperty = \"value\" } ) . Target ( ( ) => order ) ) ;
审核尺寸选项
| 选项 | 类型 | 描述 |
|---|---|---|
| EventType | 细绳 | 表示事件类型的字符串 |
| Targetgetter | func <obsect> | 目标对象getter(将对象返回跟踪的功能) |
| 外菲尔德 | 目的 | 匿名对象包含要合并到审计事件的其他字段 |
| DataProvider | AuditDataProvider | 要使用的数据提供商。默认为在audit.core.configuration.dataprovider上配置的dataprovider默认 |
| CreationPolicy | EventCreationPolicy | 要使用的创建策略。默认值是插入的 |
| Iscreateandsave | 布尔 | 值表示该范围是否应立即结束并在创建后立即保存。默认值为false |
| 审计 | 审计 | 自定义初始审核事件要使用。默认情况下,它将创建一个基本审核通讯的新实例 |
| Skipextraframes | int | 用于指示应跳过堆栈中有多少帧以确定调用方法的值。默认值为0 |
| 呼叫 | 方法库 | 在事件中存储的特定呼叫方法。默认值是使用调用堆栈确定调用方法。 |
| 项目 | 字典<字符串,对象> | 可用于在范围上存储其他信息的项目的字典,可从审计尺寸实例访问。 |
例如,考虑以下代码取消您要审核的订单:
Order order = Db . GetOrder ( orderId ) ; order . Status = - 1 ; order . OrderItems = null ; order = Db . OrderUpdate ( order ) ;
要审核此操作,您可以将代码包装在使用审核尺寸初始化的块中,并指定目标对象以进行监视:
Order order = Db . GetOrder ( orderId ) ; using ( AuditScope . Create ( \"Order:Update\" , ( ) => order ) ) { order . Status = - 1 ; order . OrderItems = null ; order = Db . OrderUpdate ( order ) ; }
笔记
不需要使用使用块,但是在审核单个代码块时,它会简化语法。它还可以通过处置时隐式保存事件来实现自动异常检测和持续时间计算。
笔记
当使用将与不同系统交互的扩展程序(例如audit.entityframework,audit.webapi等)时。您无需明确创建AuctitScope或AuditeVent,它们是由扩展程序内部创建的。
简单的记录
如果您不跟踪对象或事件的持续时间,则可以使用立即记录事件的日志快捷方式。例如:
AuditScope . Log ( \"Event Type\" , new { ExtraField = \"extra value\" } ) ;
手动节省
您可以通过创建手动审核器来控制创建和保存逻辑。例如,将一对启动/结束方法调用记录为一个事件:
public class SomethingThatStartsAndEnds { private AuditScope auditScope ; public int Status { get ; set ; } public void Start ( ) { // Create a manual scope auditScope = AuditScope . Create ( new AuditScopeOptions ( ) { EventType = \"MyEvent\" , TargetGetter = ( ) => this . Status , CreationPolicy = EventCreationPolicy . Manual } ) ; } public void End ( ) { // Save the event auditScope . Save ( ) ; // Discard to avoid further saving auditScope . Discard ( ) ; } }
有关EventCreationPolicy的更多信息,请参阅事件创建策略部分。
输出
该库将为每个操作生成一个输出(审核Vent),包括:
- 操作前后跟踪对象的状态。
- 执行时间和持续时间。
- 环境信息,例如用户,机器,域,环境等。
- 提供的评论和自定义字段。
JSON输出的一个示例:
{ \"EventType\" : \"Order:Update\" , \"Environment\" : { \"UserName\" : \"Federico\" , \"MachineName\" : \"HP\" , \"DomainName\" : \"HP\" , \"CallingMethodName\" : \"Audit.UnitTest.AuditTests.TestUpdate()\" , \"Exception\" : null , \"Culture\" : \"en-GB\" } , \"Activity\" : { \"StartTimeUtc\" : \"2023-12-01T17:36:52.2256288Z\" , \"SpanId\" : \"23a93b9e8cbc457f\" , \"TraceId\" : \"2d3e5e90f790c7d2274d9bb047531f66\" , \"ParentId\" : \"0000000000000000\" , \"Operation\" : \"Update\" } , \"StartDate\" : \"2016-08-23T11:33:14.653191Z\" , \"EndDate\" : \"2016-08-23T11:33:23.1820786Z\" , \"Duration\" : 8529 , \"Target\" : { \"Type\" : \"Order\" , \"Old\" : { \"OrderId\" : \"39dc0d86-d5fc-4d2e-b918-fb1a97710c99\" , \"Status\" : 2 , \"OrderItems\" : [ { \"Sku\" : \"1002\" , \"Quantity\" : 3.0 } ] } , \"New\" : { \"OrderId\" : \"39dc0d86-d5fc-4d2e-b918-fb1a97710c99\" , \"Status\" : - 1 , \"OrderItems\" : null } } }
输出详细信息
以下表描述了输出字段:
-
AuditeVent对象
| 字段名称 | 类型 | 描述 |
|---|---|---|
| EventType | 细绳 | 用户定义的字符串将事件分组 |
| 环境 | 环境 | 包含有关执行环境的信息 |
| StartDate | DateTime | 活动开始的日期和时间 |
| 终结 | DateTime | 活动结束的日期和时间 |
| 期间 | 整数 | 活动持续时间以毫秒为单位 |
| 目标 | 目标 | 用户定义的跟踪对象 |
| 评论 | 弦数 | 用户定义的注释 |
| Customfields | 字典 | 用户定义的自定义字段 |
-
环境对象
| 字段名称 | 类型 | 描述 |
|---|---|---|
| 用户名 | 细绳 | 当前记录的用户名 |
| Machinename | 细绳 | 执行机器名称 |
| domainname | 细绳 | 当前的用户域 |
| 呼叫methodname | 细绳 | 呼叫方法签名信息 |
| stacktrace | 细绳 | 审核范围创建时刻的完整堆栈跟踪(除非通过配置启用) |
| 例外 | 细绳 | 指示是否已检测到异常(如果未抛出任何例外,则为null) |
| 文化 | 细绳 | 当前的文化标识符 |
-
目标对象
| 字段名称 | 类型 | 描述 |
|---|---|---|
| 类型 | 细绳 | 跟踪对象类型名称 |
| 老的 | 目的 | 事件开始时跟踪对象的值 |
| 新的 | 目的 | 事件结束时跟踪对象的值 |
自定义字段和评论
审计对象提供了两种扩展事件输出的方法。
- 使用setCustomfield()方法将任何对象添加为事件的额外字段。
- 使用comment()将文本注释添加到事件的注释数组中。
例如:
Order order = Db . GetOrder ( orderId ) ; using ( var audit = AuditScope . Create ( \"Order:Update\" , ( ) => order ) ) { audit . SetCustomField ( \"ReferenceId\" , orderId ) ; order . Status = - 1 ; order = Db . OrderUpdate ( order ) ; audit . Comment ( \"Status Updated to Cancelled\" ) ; }
您还可以在创建审核尺寸时设置自定义字段,通过将所需属性作为额外字段的匿名对象传递给匿名对象。例如:
using ( var audit = AuditScope . Create ( \"Order:Update\" , ( ) => order , new { ReferenceId = orderId } ) ) { order . Status = - 1 ; order = Db . OrderUpdate ( order ) ; audit . Comment ( \"Status Updated to Cancelled\" ) ; }
您也可以直接从event.customfields属性访问自定义字段。例如:
using ( var audit = AuditScope . Create ( \"Order:Update\" , ( ) => order , new { ReferenceId = orderId } ) ) { audit . Event . CustomFields [ \"ReferenceId\" ] = orderId ; }
笔记
自定义字段不仅限于单个属性,您也可以存储任何对象,默认情况下它们将被JSON序列化。
扩展审核通风
丰富事件输出的另一种方法是创建一个从AuditeVent类继承的类,然后您可以将类的实例传递到auctitscope.create方法。例如:
public class YourAuditEvent : AuditEvent { public Guid ReferenceId { get ; set ; } = Guid . NewGuid ( ) ; } using ( var scope = AuditScope . Create ( new AuditScopeOptions { AuditEvent = new YourAuditEvent ( ) } ) ) { //... }
以前示例的输出将是:
{ \"EventType\" : \"Order:Update\" , \"Environment\" : { \"UserName\" : \"Federico\" , \"MachineName\" : \"HP\" , \"DomainName\" : \"HP\" , \"CallingMethodName\" : \"Audit.UnitTest.AuditTests.TestUpdate()\" , \"Exception\" : null , \"Culture\" : \"en-GB\" } , \"Target\" : { \"Type\" : \"Order\" , \"Old\" : { \"OrderId\" : \"39dc0d86-d5fc-4d2e-b918-fb1a97710c99\" , \"Status\" : 2 , } , \"New\" : { \"OrderId\" : \"39dc0d86-d5fc-4d2e-b918-fb1a97710c99\" , \"Status\" : - 1 , } } , \"ReferenceId\" : \"39dc0d86-d5fc-4d2e-b918-fb1a97710c99\" , // <-- Custom Field \"Comments\" : [ \"Status Updated to Cancelled\" ] , // <-- Comments \"StartDate\" : \"2016-08-23T11:34:44.656101-05:00\" , \"EndDate\" : \"2016-08-23T11:34:55.1810821-05:00\" , \"Duration\" : 8531 }
丢弃选项
审计对象具有丢弃()方法,可允许用户丢弃事件。丢弃事件意味着不会保存。
例如,如果您想避免在某些条件下保存审计事件:
using ( var scope = AuditScope . Create ( new AuditScopeOptions ( \"SomeEvent\" , ( ) => someTarget ) ) ) { try { //some operation Critical . Operation ( ) ; } catch ( Exception ex ) { //If an exception is thrown, discard the audit event scope . Discard ( ) ; } }
数据提供商
数据提供商(或存储接收器)包含逻辑来处理审核事件输出,您可以在其中定义如何使用审核日志。
您可以通过创建实现IiauditDataProvider或从AuditDataProvider继承并覆盖其方法的类来使用其中包括或注入您自己的机制的数据提供商之一:
- 插入Event:应该存储事件并返回唯一的ID。
- 替换event:应更新给定ID的事件。此方法仅用于创建策略手册或插入性链接链霉词。
如果您的数据提供商支持异步操作,则还必须实现以下方法:
- 插入EventAsync:插入方法的异步实现。
- 替换EventAsync:替换event方法的异步实现。
如果您的数据提供商将支持事件检索,则应实现以下方法:
- GetEvent:通过ID检索事件。
- GetEventAsync:GetEvent方法的异步实现。
例如:
public class MyCustomDataProvider : AuditDataProvider { public override object InsertEvent ( AuditEvent auditEvent ) { var fileName = $ \"Log { Guid . NewGuid ( ) } .json\" ; File . WriteAllText ( fileName , auditEvent . ToJson ( ) ) ; return fileName ; } public override void ReplaceEvent ( object eventId , AuditEvent auditEvent ) { var fileName = eventId . ToString ( ) ; File . WriteAllText ( fileName , auditEvent . ToJson ( ) ) ; } public override T GetEvent < T > ( object eventId ) { var fileName = eventId . ToString ( ) ; return JsonConvert . DeserializeObject < T > ( File . ReadAllText ( fileName ) ) ; } // async implementation: public override async Task < object > InsertEventAsync ( AuditEvent auditEvent , CancellationToken cancellationToken = default ) { var fileName = $ \"Log { Guid . NewGuid ( ) } .json\" ; await File . WriteAllTextAsync ( fileName , auditEvent . ToJson ( ) , cancellationToken ) ; return fileName ; } public override async Task ReplaceEventAsync ( object eventId , AuditEvent auditEvent , CancellationToken cancellationToken = default ) { var fileName = eventId . ToString ( ) ; await File . WriteAllTextAsync ( fileName , auditEvent . ToJson ( ) , cancellationToken ) ; } public override async Task < T > GetEventAsync < T > ( object eventId , CancellationToken cancellationToken = default ) { var fileName = eventId . ToString ( ) ; return await GetFromFileAsync < T > ( cancellationToken ) ; } }
数据提供商选择
可以为整个应用程序或每个审核范围全球设置数据提供商。
笔记
如果您不指定全局数据提供商,它将默认为将事件作为.json文件登录到当前工作目录中的filedataprovider。
要设置全局数据提供商,请在静态审核上分配DataProvider属性。例如:
Audit . Core . Configuration . DataProvider = new MyCustomDataProvider ( ) ;
或使用Fluent API使用()方法:
Audit . Core . Configuration . Setup ( ) . Use ( new MyCustomDataProvider ( ) ) ;
要将数据提供商按每个范围设置,请在创建AuctitScope时使用AuctitScopeOptions。例如:
var scope = AuditScope . Create ( new AuditScopeOptions { DataProvider = new MyCustomDataProvider
