背景
一個成熟的系統,都會針對一些關鍵的操作,去創建用戶操作日誌。
比如:
XX人創建了一條訂單,訂單號:XXXXXXXXX
因爲操作人
或者訂單號
是動態的,所以有些開發人員,不知道獲取,就將這種操作日誌和業務代碼融在一起。
我們當然要杜絕這種現象,一定會有更好的解決方案。
當前項目除了滿足上面這個基礎需求場景外,還可以滿足一些常見的日誌記錄需求。
下面通過一些測試用例來了解下當前項目吧。
一、支持SpEL表達式
1、使用場景
我們在記錄操作日誌的時候,爲了獲取接口中的入參信息,就可以通過SpEL表達式。
2、接口示例
@GetMapping(value = "/queryUser")
@OperateLog(bizNo = "{#userName}", operateName = "查詢用戶", operateContent = "通過 {#userName} 查詢用戶")
public Result<String> queryUser(@RequestParam String userName) {
return Result.success(userName);
}
這裏入參 userName
的獲取,就是通過SpEL表達式獲取到
3、請求接口
http://localhost:8080/queryUser?userName=James
4、輸出日誌
日誌操作記錄------ OperateLogDTO(operator=張三, bizNo=James, operateName=查詢用戶, operateContent=通過 James 查詢用戶, status=true, errMsg=null)
可以看出通過SpEL表達式,已經將 {#userName}
佔位符,成功替換請求的參數 James
。
二、支持函數表達式
1、使用場景
有些時候我們僅僅是獲取請求參數的數據還不夠,還需要拿着請求參數的數據,去請求其它接口,才能組成一條完整的日誌,最典型的場景就是
商品ID爲 XXX 的商品的名稱已經從 XXX 改成 XXX
這裏前端肯定只會傳當前的商品ID和當前修改後的商品名稱,也就是說該商品老的名稱還需要通過商品ID去商品表查完後,才能組成完整日誌。
2、接口示例
@GetMapping(value = "/deleteUser")
@OperateLog(bizNo = "{#userId}", operateName = "刪除用戶",
operateContent = "用戶id爲 {#userId} 用戶名爲 [getUserNameByUserId{#userId}] 已被刪除")
public Result<Void> deleteUser(Long userId) {
return Result.success();
}
3、請求接口
http://localhost:8080/deleteUser?userId=888
4、輸出日誌
日誌操作記錄------ OperateLogDTO(operator=張三, bizNo=888, operateName=刪除用戶, operateContent=用戶id爲 888 用戶名爲 張老三 已被刪除, status=true, errMsg=null)
這裏用戶名張老三
,是模擬查詢數據庫獲取的用戶名。
三、支持三目表達式
1、使用場景
有時候我們可能根據是否傳主鍵id來判斷是新增還是更新,或者傳不同的type來確定什麼操作類型。
2、接口示例
@PostMapping(value = "/saveOrUpdateUser")
@OperateLog(bizNo = "{#dto.userId}", operateName = "#dto.userId == null ? '新增用戶':'更新用戶'",
operateContent = "#dto.userId == null ? '新增' + #dto.userName + '用戶':'將用戶id爲' + #dto.userId + '的用戶名更新爲' + #dto.userName")
public Result<Void> saveOrUpdateUser(@RequestBody UserDTO dto) {
return Result.success();
}
3、請求示例
請求url
localhost:8080/saveOrUpdateUser
請求參數
{
"userId": 17,
"userName": "趙磊"
}
4、輸出日誌
傳入userId的日誌
日誌操作記錄------ OperateLogDTO(operator=張三, bizNo=null, operateName=更新用戶, operateContent=將用戶id爲17的用戶名更新爲趙磊, status=true, errMsg=null)
如果不傳入userId只傳userName,我們再看下日誌
日誌操作記錄------ OperateLogDTO(operator=張三, bizNo=null, operateName=新增用戶, operateContent=新增趙磊用戶, status=true, errMsg=null)
四、支持標記成功日誌或業務異常日誌
1、使用場景
請求一個接口的時候,可以分爲三種情況:
- 接口返回成功,同時返回成功狀態碼
- 接口返回成功,但返回業務異常狀態碼,比如:沒有查詢到該訂單信息
- 接口直接報錯,比如我們常見的空指針異常
對於第三種情況,我們可以不去記錄這個用戶操作日誌,如果有需要可以記錄在異常記錄表中。
但對於第一和第二種情況,我們需要記錄操作是成功還是失敗。
2、接口示例
@PostMapping(value = "/saveUser")
@OperateLog(bizNo = "{#dto.userId}", operateName = "新增用戶", operateContent = "新增用戶名爲{#dto.userName}")
public Result<Void> saveUser(@RequestBody UserDTO dto) {
return Result.failed("該用戶名稱已存在");
}
可以看出接口返回的是 該用戶名稱已存在
,業務異常。
3、請求示例
請求url
localhost:8080/saveUser
請求參數
{
"userId": 2,
"userName": "閻平"
}
4、輸出日誌
日誌操作記錄------ OperateLogDTO(operator=張三, bizNo=2, operateName=新增用戶, operateContent=新增用戶名爲閻平, status=false, errMsg=該用戶名稱已存在)
可以看出這裏的status狀態是 false
,同時記錄了錯誤原因 該用戶名稱已存在
。
最後附上GitHub源碼地址:
https://github.com/yudiandemingzi/spring-boot-operate-log
聲明: 公衆號如需轉載該篇文章,發表文章的頭部一定要 告知是轉至公衆號: 後端元宇宙。同時也可以問本人要markdown原稿和原圖片。其它情況一律禁止轉載!