1. 程式人生 > 實用技巧 >.NetCore實現審計日誌

.NetCore實現審計日誌

審計日誌的概念

維基百科:審計跟蹤(也稱為稽核日誌)是一個安全相關的時間順序記錄,記錄這些記錄的目的是為已經影響在任何時候的詳細操作,提供程式執行的證明檔案記錄、源或事件

​ 今天我們參照ABP的審計功能來為AdmBoots實現一個審計日誌,它能自動記錄所有與應用的互動和有意的方法呼叫和呼叫者資訊與引數,包括:

  • 呼叫者id,
  • 呼叫者姓名
  • 被呼叫的服務名
  • 被呼叫的方法名
  • 執行引數
  • 執行時間
  • 執行時長
  • 客戶端IP
  • 客戶端電腦名
  • 呼叫異常

有了這些資訊,可以方便地檢視每次請求介面所耗的時間,能夠幫助我們快速定位到某些效能有問題的介面。有了這些資料之後,我們就可以很方便地復現介面產生 BUG 時的一些環境資訊。

當然如果你腦洞更大的話,可以根據這些資料來開發一個視覺化的圖形介面,方便開發與測試人員來快速定位問題。

啟動流程

審計日誌的實現,就是在每次呼叫介面/方法時將相關資訊記錄下來並將其寫入到資料庫表 AuditLog 當中。

那麼,如何獲取每次呼叫介面/方法的相關資訊呢?可以通過以下三種方式來解決:

  • [x] 過濾器
  • [x] 攔截器

其核心思想十分簡單,就是在執行具體介面方法的時候,先使用 StopWatch 物件來記錄執行完一個方法所需要的時間,並且還能夠通過 HttpContext 來獲取到一些客戶端的關鍵資訊。

本篇主要講解使用過濾器實現審計日誌,攔截器處理時的總體思路與過濾器類似,只不過由於攔截器不僅僅是處理 介面,也會處理內部的一些型別的方法,所以針對同步方法與非同步方法的處理肯定會複雜一點。如何使用攔截器實現該功能可以參考

AdmBoots的工作單元實現,基本思路都一樣。

實現過程

建立審計日誌模型

 	[Table("AuditLog")]
    public class AuditLog : Entity {

        /// <summary>
        /// 使用者ID
        /// </summary>
        public int? UserId { get; set; }

        /// <summary>
        /// 使用者姓名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 服務 (類/介面) 名
        /// </summary>
        public string ServiceName { get; set; }

        /// <summary>
        /// 執行方法名稱
        /// </summary>
        public string MethodName { get; set; }

        /// <summary>
        /// 呼叫引數
        /// </summary>
        public string Parameters { get; set; }

        /// <summary>
        /// 返回值
        /// </summary>
        public string ReturnValue { get; set; }

        /// <summary>
        /// 方法執行的開始時間
        /// </summary>
        public DateTime ExecutionTime { get; set; }

        /// <summary>
        /// 方法呼叫的總持續時間(毫秒)
        /// </summary>
        public int ExecutionDuration { get; set; }

        /// <summary>
        /// 客戶端的IP地址
        /// </summary>
        public string ClientIpAddress { get; set; }

        /// <summary>
        /// 客戶端的名稱(通常是計算機名)
        /// </summary>
        public string ClientName { get; set; }

        /// <summary>
        /// 瀏覽器資訊
        /// </summary>
        public string BrowserInfo { get; set; }

        /// <summary>
        /// 方法執行期間發生異常
        /// </summary>
        public string Exception { get; set; }

        /// <summary>
        /// 自定義資料
        /// </summary>
        public string CustomData { get; set; }
    }