在某企業級專案中,需記錄操作人員、時間、模組、原始資料(列級)與變更後資料。初期系統架構缺乏統一日誌介面,各模組方法獨立、參數型別/順序/命名不一,導致硬編碼植入日誌極其繁瑣且難以維護。
採用 @BussAnnotation 標註業務語義(模組、操作類型),搭配 @Around 環繞通知攔截目標方法。
@Aspect
@Component
public class LogInterceptor {
@Pointcut("@annotation(com.xxx.BussAnnotation)")
public void bizPointcut() {}
@Around("bizPointcut() && @annotation(anno)")
public Object logAround(ProceedingJoinPoint pjp, BussAnnotation anno) throws Throwable {
// 1. 解析註解元資料:anno.moduleName(), anno.option()
// 2. 透過 pjp.getArgs() 獲取入參,配合 JSON 序列化保存完整物件圖
// 3. 執行目標方法:Object result = pjp.proceed();
// 4. 記錄回傳值/異常,非同步持久化至資料庫/ES
return result;
}
}
現狀:addUser(User u)、updateUser(User u, String x) 參數位置、型別不固定。
對策:
@LogField 註解標註需追蹤的欄位,AOP 掃描註解自動構建變更集。方案:
BlockingQueue,專用執行緒批次落庫。@Sensitive 註解,序列化時自動遮罩(身分證、手機、金額等)。無法捕獲 Service/DAO 層的細粒度資料變更,故不作為主流方案。
| 階段 | 推薦方案 | 關鍵技術點 |
|---|---|---|
| 專案初期/小型 | Log4j MDC + 自定義 Appender | 零侵入、快速上線、結構化資料用 JSON 存儲 |
| 業務穩定/中型 | AOP + 統一註解規範 | 強制參數規範、欄位級註解、非同步落庫 |
| 大型/微服務 | 分散式追蹤(SkyWalking/Zipkin)+ 變更資料捕獲(CDC) | 資料庫 Binlog 解析、服務網格側車、統一日誌平台 |
OperationLog 統一實體:traceId、operator、module、action、entityType、entityId、beforeJson、afterJson、duration、status。@AuditLog(module="用戶管理", action="UPDATE") 統一註解,替代散落的硬編碼。「日誌不是寫給機器看的,是寫給半夜排查 Bug 的自己看的。」—— 統一規範、非同步落庫、欄位脫敏,三者缺一不可。