WangHan
2024-09-12 d5855a4926926698b740bc6c7ba489de47adb68b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package tech.powerjob.server.web;
 
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import tech.powerjob.server.common.utils.AOPUtils;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
 
/**
 * 使用AOP记录访问日志
 *
 * @author tjq
 * @since 2020/6/5
 */
@Aspect
@Component
@Slf4j(topic = "WEB_LOG")
public class WebLogAspect {
 
    /**
     * 定义切入点
     * 第一个*:标识所有返回类型
     * 字母路径:包路径
     * 两个点..:当前包以及子包
     * 第二个*:所有的类
     * 第三个*:所有的方法
     * 最后的两个点:所有类型的参数
     */
    @Pointcut("execution(public * tech.powerjob.server.web.controller..*.*(..))")
    public void include() {
    }
 
    @Pointcut("execution(public * tech.powerjob.server.web.controller.ServerController.*(..))")
    public void exclude() {
    }
 
    @Pointcut("include() && !exclude()")
    public void webLog() {
    }
 
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            // 获取请求域
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (requestAttributes == null) {
                return;
            }
            HttpServletRequest request = requestAttributes.getRequest();
 
 
            String classNameMini = AOPUtils.parseRealClassName(joinPoint);
            String classMethod = classNameMini + "." + joinPoint.getSignature().getName();
 
            // 排除特殊类
 
            // 192.168.1.1|POST|com.xxx.xxx.save|请求参数
            log.info("{}|{}|{}|{}", request.getRemoteAddr(), request.getMethod(), classMethod, stringify(joinPoint.getArgs()));
        }catch (Exception e) {
            // just for safe
            log.error("[WebLogAspect] aop occur exception, please concat @KFCFans to fix the bug!", e);
        }
    }
 
    /**
     * 序列化请求对象,需要特殊处理无法序列化的对象(HttpServletRequest/HttpServletResponse)
     * @param args Web请求参数
     * @return JSON字符串
     */
    private static String stringify(Object[] args) {
        if (ArrayUtils.isEmpty(args)) {
            return null;
        }
        List<Object> objList = Lists.newLinkedList();
        for (Object obj : args) {
            if (obj instanceof HttpServletRequest || obj instanceof HttpServletResponse) {
                break;
            }
            // FatJar
            if (obj instanceof MultipartFile || obj instanceof Resource) {
                break;
            }
 
            objList.add(obj);
        }
        return JSONObject.toJSONString(objList);
    }
}