我们已经不用 AOP 做日志很久了!
前言
用戶在操作我們系統(tǒng)的過程中,針對一些重要的業(yè)務(wù)數(shù)據(jù)進(jìn)行增刪改查的時候,我們希望記錄一下用戶的操作行為,以便發(fā)生問題時能及時的找到依據(jù),這種日志就是業(yè)務(wù)系統(tǒng)的操作日志。
本篇我們來探討下常見操作日志的實(shí)現(xiàn)方案和可行性
常見的操作日志類型
-
用戶登錄日志
-
重要數(shù)據(jù)查詢?nèi)罩?(但電商可能不重要的數(shù)據(jù)也做埋點(diǎn),比如在淘寶上你搜索什么商品,即使不買,一段時間內(nèi)首頁也會給你推薦類似的東西)
-
重要數(shù)據(jù)變更日志 (如密碼變更,權(quán)限變更,數(shù)據(jù)修改等)
-
數(shù)據(jù)刪除日志
-
......
總結(jié)來說,就是重要的增刪改查根據(jù)業(yè)務(wù)的需要來做操作日志的埋點(diǎn)。
實(shí)現(xiàn)方案對比
基于AOP(切面)傳統(tǒng)的實(shí)現(xiàn)方案
-
優(yōu)點(diǎn):實(shí)現(xiàn)思路簡單;
-
缺點(diǎn):增加數(shù)據(jù)庫的負(fù)擔(dān),強(qiáng)依賴前端的傳參,不方便拓展,不支持批量操作,不支持多表關(guān)聯(lián);
基于數(shù)據(jù)庫Binlog
-
優(yōu)點(diǎn):解除了數(shù)據(jù)新舊變化的耦合,支持批量操作,方便多表關(guān)聯(lián)拓展,不依賴開發(fā)語言;
-
缺點(diǎn):數(shù)據(jù)庫表設(shè)計需要統(tǒng)一的約定;
方案實(shí)現(xiàn)細(xì)節(jié)
一、基于AOP切面+注解的傳統(tǒng)方案
傳統(tǒng)的做法就是切面+注解的方式,這種對代碼的侵入性不強(qiáng),通常記錄ip、業(yè)務(wù)模塊、操作賬號、操作場景、操作來源等等,一般在注解+攔截器里這些值都拿得到,如下圖所示:
這種常見的我們在通用方法都可以處理,但是在數(shù)據(jù)變更方面,一直沒有較好的實(shí)現(xiàn)方式,比如數(shù)據(jù)在變更前是多少,變更后是多少。
以我們以前實(shí)現(xiàn)的一套方案來說,基于數(shù)據(jù)變更的記錄方式不僅要和需求方約定好模板(上百個字段的不可能都做展示和記錄),也要和前端做一些約定,比如在修改之前的值是多少,修改后的值是多少,如下代碼客官請看:
????@Valid@NotNull(message?=?"新值不能為空")@UpdateNewDataOperationLogprivate?T?newData;@Valid@NotNull(message?=?"舊值不能為空")@UpdateOldDataOperationLogprivate?T?oldData;存在的問題:
-
1.舊值如果不多查詢一次數(shù)據(jù)庫則需要依賴前端把舊值封裝到oldData對象中,很有可能已經(jīng)不是修改前的值;
-
2.無法處理批量的List數(shù)據(jù);
-
3.不支持多表操作;
再以一個場景為例,再刪除之前需要記錄刪除前的值,是不是還得再查一次~
????@PostMapping("/delete")@ApiOperation(value?=?"刪除用戶信息",?notes?=?"刪除用戶信息")@DeleteOperationLog(system?=?SystemNameNewEnum.SYS_JMS_LMDM,?module?=?ModuleNameNewEnum.LMDM_AUTH,?table?=?LogBaseTableNameEnum.TABLE_USER,?methodName?=?"detail")二、基于數(shù)據(jù)庫Binlog 方案
系統(tǒng)架構(gòu)圖如下:
「主要分為3塊:」
-
1:業(yè)務(wù)應(yīng)用 生成每次操作的traceid,并更新到操作的業(yè)務(wù)表中,發(fā)送1條業(yè)務(wù)消息,包含當(dāng)前操作的操作人相關(guān)的信息;
-
2:日志收集應(yīng)用 對業(yè)務(wù)日志和轉(zhuǎn)換后的binlog日志做整合,提供對外的日志查詢搜索API;
-
3:日志處理應(yīng)用
-
利用canal采集和解析業(yè)務(wù)庫的binlog日志并投遞到kafka中,解析后的記錄中記錄了當(dāng)前操作的操作類型,如屬于刪除、修改、新增,和新舊值的記錄,格式如下:
-
處理完binlon日志轉(zhuǎn)換后的操作日志,如下:
??{"id":"120716921250250776","relevanceInfo":"XX0000097413282,","remark":"簽收財務(wù)網(wǎng)點(diǎn)編碼由【】改為【380000】,簽收網(wǎng)點(diǎn)名稱由【】改為【泉州南安網(wǎng)點(diǎn)】,簽收網(wǎng)點(diǎn)code由【】改為【2534104】,運(yùn)單狀態(tài)code由【204】改為【205】,簽收財務(wù)網(wǎng)點(diǎn)名稱由【】改為【福建代理區(qū)】,簽收網(wǎng)點(diǎn)id由【0】改為【461】,簽收標(biāo)識,1是,0否由【0】改為【1】,簽收時間由【null】改為【2020-04-24?21:09:47】,簽收財務(wù)網(wǎng)點(diǎn)id由【0】改為【400】,","traceId":"120716921250250775"}庫表設(shè)計
-
1:所有業(yè)務(wù)系統(tǒng)表需要添加trace_id字段,每次操作生成一個隨機(jī)字符串并保存到業(yè)務(wù)表中;
-
2:日志收集應(yīng)用庫表設(shè)計
效果
基于binlog實(shí)現(xiàn)方案未來規(guī)劃
優(yōu)化發(fā)送業(yè)務(wù)消息的實(shí)現(xiàn),使用切面攔截減少對業(yè)務(wù)代碼的侵入;
目前暫時不支持對多表關(guān)聯(lián)操作日志記錄,需要拓展;
總結(jié)
本文以操作日志為題材討論了操作日志的實(shí)現(xiàn)方案和可行性,并且都已經(jīng)在功能上進(jìn)行實(shí)現(xiàn),其中使用aop方案也是大部分中小企業(yè)的首選實(shí)現(xiàn)方案,但是在一些金融領(lǐng)域以及erp相關(guān)系統(tǒng),對操作日志記錄明細(xì)要求極高,常見技術(shù)方案很難滿足,即使能夠滿足也會帶來一些代碼強(qiáng)侵入以及性能問題。
所以我們又討論了基于binlog實(shí)現(xiàn)的方案,該方案雖然比對aop來說增強(qiáng)了技術(shù)的復(fù)雜性,但是對于有一定技術(shù)積累的團(tuán)隊(duì)來說不算什么難事,并且該方案我們都實(shí)現(xiàn)了上線,并且解決了代碼層面上的侵入,屬于跨語言級別的,相信對讀者還是有一定的啟發(fā)。
總結(jié)
以上是生活随笔為你收集整理的我们已经不用 AOP 做日志很久了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试官:BigDecimal 一定不会丢
- 下一篇: Redis性能监控指标汇总