PostgreSQL觸發器,日誌審計小神器 最近遇到的項目問題,審計日誌記錄不夠詳細,比如某用戶編輯了某台設備,只記錄了用戶操作的設備名、操作時間、登錄用戶和登錄IP,至於設備其他屬性編輯前和編輯後的信息就沒有更詳細的對比了,審計粒度不夠細,顯然是不能讓客戶滿意的,秉承客戶滿意優先原則,只好技術加持 ...
PostgreSQL觸發器,日誌審計小神器
最近遇到的項目問題,審計日誌記錄不夠詳細,比如某用戶編輯了某台設備,只記錄了用戶操作的設備名、操作時間、登錄用戶和登錄IP,至於設備其他屬性編輯前和編輯後的信息就沒有更詳細的對比了,審計粒度不夠細,顯然是不能讓客戶滿意的,秉承客戶滿意優先原則,只好技術加持一波了。
實際客戶想要記錄的更多,涉及的業務屬性比較廣,返本溯源,我們決定在資料庫層面解決,以期能最少的改動業務代碼。
利用PostgreSql觸發器在源表數據發生變化的時候準備一張對應表進行備份記錄,把變化數據就像提交svn一樣插入到歷史表中,如圖
解決方案有了,但其實還存在一個問題觸發器只在資料庫內部運行,如何記錄是當前是哪個登錄用戶對數據源進行的變更還是個問題,經過一位大佬的指導,可以利用PostgreSql的會話變數解決,簡單的測試代碼如下
列印結果
這樣就可以利用資料庫會話變數的特性,在每一次的資料庫變更前,先將全局操作pid關聯到用戶uid為一張表,而變更的時候,將將全局操作pid插入到歷史數據表中,這樣通過唯一的全局操作pid就可以關聯查詢出是哪個用戶的操作了。
於是解決方案圖變為
開心的代碼實現
創建審計主表
創建審計歷史表
創建用戶id和操作id關聯表
在用戶進行數據操作變更的postgresql連接時,我們都先將資料庫全局變數插入到operation_log表中,將當前登錄的用戶id與這次變更操作綁定在一起,這個可以封裝在web框架層實現。
創建觸發器
觸發器函數定義了觸發器被觸發後執行的操作,下麵列一下觸發器函數中可以使用的變數,例子中的 OLD,就表示觸發操作的舊數據行,詳細如下:
l NEW:INSERT、UPDATE 操作觸發的行級觸發器中存儲的新的數據行,
l OLD:INSERT、UPDATE 操作觸發的行級觸發器中存儲的的數據行,
l TG_OP:代表當前觸發器監聽到的操作類型,數據類型為 text,內容為 INSERT、UPDATE、DELETE、TRUNCATE。
小結
本文只是大概如何利用PostgreSql觸發器對用戶行為進行詳細日誌審計,旨在提供一個觸發器記錄數據源變更和web框架結合的思路,希望對你有所幫助,如果你有更好的解決方案可以留言告訴我哦
PS:如果文章對你有價值,歡迎點個推薦。