WangHan
2025-04-02 a8ba678a3fe5a39da2c732014cebbb66e408e97c
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
package com.iplatform.base.support;
 
import com.iplatform.base.AsyncManager;
import com.iplatform.base.service.ApiTimeServiceImpl;
import com.iplatform.model.vo.ApiTime;
import com.walker.infrastructure.utils.DateUtils;
import com.walker.infrastructure.utils.NumberGenerator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
 
import java.util.TimerTask;
 
/**
 * 统计接口调用时间拦截器实现。
 * <pre>
 *     1) 拦截所有接口
 *     2) 如果接口调用时间小于阈值,则只计算累加调用量;
 *     3) 如果接口调用时间大于阈值,则会记录详细内容:接口位置、时间、耗时等
 *     4) 写入数据库结果并非实时,而是会实时写入缓存,等到触发机制时才会刷盘。触发机制如下:
 *
 *       4.1) 计数到达
 *       4.2) 访问结果接口,查询统计结果时
 *
 *     5) 统计结果接口地址:/test/time/statistics
 * </pre>
 * @author 时克英
 * @date 2024-02-29
 */
public class TimeStatisticsInterceptor implements HandlerInterceptor {
 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
//        String uri = request.getRequestURI();
        if(this.enabled){
            long startTime = System.nanoTime();
            request.setAttribute("startTime", startTime);
        }
        return true;
 
//        if (url.indexOf("/list") >= 0) {
//            this.logger.debug("拦截器执行:preparePageSearch()");
//            this.preparePageSearch(request);
//        }
//        return this.doPreHandleOther(url, request, response);
    }
 
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object args, Exception exception) throws Exception {
        if(this.enabled){
            Object startTimeObj = request.getAttribute("startTime");
            if(startTimeObj != null){
                long startTime = Long.parseLong(startTimeObj.toString());
                long costTime = (System.nanoTime() - startTime);
                // 小于1毫秒的显示为0
                if(costTime < 1000000){
                    costTime = 0;
                } else {
                    costTime = costTime / 1000000;
                }
                ApiTime apiTime = new ApiTime();
                apiTime.setId(NumberGenerator.getLongSequenceNumber());
                apiTime.setCreateTime(DateUtils.getDateTimeNumber());
                long currentDate = DateUtils.getDateNumber(System.currentTimeMillis());
                apiTime.setRequestDate((int)currentDate);
                apiTime.setUri(request.getRequestURI());
                apiTime.setCostTime(costTime);
                AsyncManager.me().execute(this.acquireOperateLogTask(apiTime));
            }
        }
    }
 
    private TimerTask acquireOperateLogTask(ApiTime apiTime){
        return new TimerTask() {
            @Override
            public void run() {
                apiTimeService.execInsertApiTime(apiTime);
            }
        };
    }
 
    public void setApiTimeService(ApiTimeServiceImpl apiTimeService) {
        this.apiTimeService = apiTimeService;
    }
 
    /**
     * 是否启用接口时间拦截。
     * @param enabled
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
 
    private boolean enabled = false;
    private ApiTimeServiceImpl apiTimeService;
}