簡介
主要記錄一下項目中的日志攔截和異常攔截,由於之前公司項目為單體項目,所使用的日志攔截較為簡單,只是用攔截器進行前后對日志的攔截,異常攔截直接使用@ExceptionHandler,而現在公司接口使用的dubbo協議通信,一個網關將http協議轉為dubbo協議調用,屬於分布式項目,日志記錄我覺得有點意思,是我之前所沒有想到的。
主要流程
前提是公司所有的請求參數都封裝到一個對象中,然后該類繼承自一個DefaultRequest類,該類中有統一的封裝參數,如requestId等等。
首先請求到了網關,網關分派一個唯一requestId存儲到請求對象中,然后轉發到對應的服務中,如果對應的服務繼續調用其他的服務則繼續將該requestId傳遞下去,這樣通過requestId就可以找到所有的相關日志了。
而在日志的攔截上使用的是aop環繞通知攔截的,順帶把異常信息也攔截了,但是大家注意只要攔截接口層,不要攔截業務層,否則聲明式事務將會失效
aop代碼
這里我就不貼公司代碼了,我自己模擬一下
1@Component
2@Aspect
3@Slf4j
4public class LogAop {
5
6 @Pointcut("execution(public * com.xiaoguo.web.controller.*.*(..))")
7 public void point() {
8 }
9
10
11 @Around("point()")
12 public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
13 long startTime = System.currentTimeMillis();
14 //對參數進行分析
15 Object firstArg = proceedingJoinPoint.getArgs()[0];
16 String requestId = "test";
17 if (firstArg instanceof DefaultRequest) {
18 requestId = ((DefaultRequest) firstArg).getRequestId();
19 }
20 log.info("{}請求開始: {}", requestId, startTime);
21 Object obj = null;
22 try {
23 obj = proceedingJoinPoint.proceed();
24 }
25 //自定義異常攔截(這里用 RuntimeException 暫時代替一下明白意思就行)
26 catch (RuntimeException r) {
27 long endTime = System.currentTimeMillis();
28 log.info("{}xxx{}: {}", requestId, r.getMessage(), endTime - startTime, r);
29 return r.getMessage();
30 }
31 //未知異常攔截
32 catch (Exception e) {
33 long endTime = System.currentTimeMillis();
34 log.info("{}異常結束: {}", requestId, endTime - startTime, e);
35 return "fail";
36 }
37 long endTime = System.currentTimeMillis();
38 log.info("{}請求結束: {}", requestId, endTime - startTime);
39 return obj;
40 }
41
42 @Data
43 class DefaultRequest {
44 private String requestId;
45 }
46
47}