统计:基础

This commit is contained in:
Jerry Yan 2025-04-08 14:33:29 +08:00
parent f17e2364b6
commit fe0397af8e
11 changed files with 247 additions and 0 deletions

View File

@ -0,0 +1,7 @@
package com.ycwl.basic.stats.biz;
import org.springframework.stereotype.Component;
@Component
public class StatsBiz {
}

View File

@ -0,0 +1,43 @@
package com.ycwl.basic.stats.controller;
import com.ycwl.basic.annotation.IgnoreToken;
import com.ycwl.basic.stats.dto.AddTraceReq;
import com.ycwl.basic.stats.service.StatsService;
import com.ycwl.basic.stats.util.StatsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/trace/v1")
public class TraceController {
@Autowired
private StatsService statsService;
@IgnoreToken
@PostMapping("/start")
public void startTrace(HttpServletRequest request, HttpServletResponse response) {
String traceId = request.getHeader("traceId");
if (traceId == null || traceId.isEmpty()) {
traceId = StatsUtil.createUuid();
response.setHeader("Set-TraceId", traceId);
}
statsService.addStats(traceId, null);
}
@IgnoreToken
@PostMapping("/add")
public void addTrace(HttpServletRequest request, HttpServletResponse response, @RequestBody AddTraceReq req) {
String traceId = request.getHeader("traceId");
if (traceId == null || traceId.isEmpty()) {
traceId = StatsUtil.createUuid();
response.setHeader("Set-TraceId", traceId);
}
statsService.addRecord(traceId, req.getAction(), req.getIdentifier(), req.getParams());
}
}

View File

@ -0,0 +1,10 @@
package com.ycwl.basic.stats.dto;
import lombok.Data;
@Data
public class AddTraceReq {
private String action;
private String identifier;
private String params;
}

View File

@ -0,0 +1,18 @@
package com.ycwl.basic.stats.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("t_stats")
public class StatsEntity {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String traceId;
private Long memberId;
private Date createTime;
}

View File

@ -0,0 +1,20 @@
package com.ycwl.basic.stats.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("t_stats_record")
public class StatsRecordEntity {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String traceId;
private String action;
private String identifier;
private String params;
private Date createTime;
}

View File

@ -0,0 +1,63 @@
package com.ycwl.basic.stats.interceptor;
import com.ycwl.basic.annotation.IgnoreLogReq;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.stats.service.StatsService;
import com.ycwl.basic.stats.util.StatsUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashSet;
@Component
public class StatsInterceptor implements HandlerInterceptor {
@Autowired
private StatsService statsService;
// 在请求处理前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
request.setAttribute("startTime", System.currentTimeMillis());
String requestURI = request.getRequestURI();
String method = request.getMethod();
String traceId = request.getHeader("traceId");
if (StringUtils.isEmpty(traceId)) {
return true;
// traceId = StatsUtil.createUuid();
// response.setHeader("Set-TraceId", traceId);
// statsService.addStats(traceId, null);
}
if (handlerMethod.getMethodAnnotation(IgnoreLogReq.class) == null) {
statsService.addRecord(traceId, "REQUEST",method + " " + requestURI, null);
}
if (StringUtils.isNotEmpty(BaseContextHandler.getUserId())) {
statsService.updateStats(traceId, Long.valueOf(BaseContextHandler.getUserId()));
}
// 返回 true 继续后续流程false 终止请求
return true;
}
// 控制器方法执行后渲染视图前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
// 请求完全完成后执行无论是否异常
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// long startTime = (Long) request.getAttribute("startTime");
// long endTime = System.currentTimeMillis();
// System.out.println("【AfterCompletion】请求结束耗时" + (endTime - startTime) + "ms");
}
}

View File

@ -0,0 +1,9 @@
package com.ycwl.basic.stats.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ycwl.basic.stats.entity.StatsEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StatsMapper extends BaseMapper<StatsEntity> {
}

View File

@ -0,0 +1,9 @@
package com.ycwl.basic.stats.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ycwl.basic.stats.entity.StatsRecordEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StatsRecordMapper extends BaseMapper<StatsRecordEntity> {
}

View File

@ -0,0 +1,9 @@
package com.ycwl.basic.stats.service;
public interface StatsService {
void addStats(String traceId, Long memberId);
void updateStats(String traceId, Long memberId);
void addRecord(String traceId, String action, String identifier, String params);
}

View File

@ -0,0 +1,50 @@
package com.ycwl.basic.stats.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ycwl.basic.stats.entity.StatsEntity;
import com.ycwl.basic.stats.entity.StatsRecordEntity;
import com.ycwl.basic.stats.mapper.StatsMapper;
import com.ycwl.basic.stats.mapper.StatsRecordMapper;
import com.ycwl.basic.stats.service.StatsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class StatsServiceImpl implements StatsService {
@Autowired
private StatsMapper statsMapper;
@Autowired
private StatsRecordMapper statsRecordMapper;
@Override
public void addStats(String traceId, Long memberId) {
StatsEntity entity = new StatsEntity();
entity.setTraceId(traceId);
entity.setMemberId(memberId);
entity.setCreateTime(new Date());
statsMapper.insert(entity);
}
@Override
public void updateStats(String traceId, Long memberId) {
StatsEntity entity = new StatsEntity();
entity.setMemberId(memberId);
LambdaQueryWrapper<StatsEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StatsEntity::getTraceId, traceId);
statsMapper.update(entity, queryWrapper);
}
@Override
public void addRecord(String traceId, String action, String identifier, String params) {
StatsRecordEntity entity = new StatsRecordEntity();
entity.setTraceId(traceId);
entity.setAction(action);
entity.setIdentifier(identifier);
entity.setParams(params);
entity.setCreateTime(new Date());
statsRecordMapper.insert(entity);
}
}

View File

@ -0,0 +1,9 @@
package com.ycwl.basic.stats.util;
import java.util.UUID;
public class StatsUtil {
public static String createUuid() {
return UUID.randomUUID().toString().replace("-", "");
}
}