接口上加注解EpcLog 并加备注 可存储操作日志

This commit is contained in:
yuezhihang
2022-02-16 16:07:40 +08:00
parent 658058a84f
commit 5206fe004b
15 changed files with 349 additions and 11 deletions
@@ -0,0 +1,24 @@
package com.adc.da.Log;
public enum BusinessType {
/**
* 其他
*/
OTHER,
/**
* 新增
*/
INSERT,
/**
* 修改
*/
UPDATE,
/**
* 删除
*/
DELETE,
/**
* 查询
*/
SEARCH,
}
@@ -0,0 +1,28 @@
package com.adc.da.Log;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EpcLog {
String value() default "";
/**
* 模块
*/
public String title() default "";
/**
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER;
String description();
}
@@ -0,0 +1,145 @@
package com.adc.da.Log;
import com.adc.da.slrs.sysLog.entity.SysLog;
import com.adc.da.slrs.sysLog.service.ISysLogService;
import com.adc.da.util.LoginUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Aspect
@Component
@Slf4j
public class logs {
//日志 注解方式存储日志
long beginTime;
@Autowired
ISysLogService sysLogService;
@Autowired(required = false)
private HttpServletRequest request;
// 配置织入点
@Pointcut("@annotation(EpcLog)")
public void logPointCut() {
log.info("=================已进入监听==========");
beginTime = System.currentTimeMillis();
}
/**
* 后置通知(在方法执行之后并返回数据) 用于拦截Controller层无异常的操作
* @param joinPoint 切点
*/
@AfterReturning("logPointCut()")
public void after(JoinPoint joinPoint){
Executor executor = Executors.newCachedThreadPool();
try {
String description = getControllerMethodInfo(joinPoint).get("description").toString();
Map<String, String[]> logParams = request.getParameterMap();
// String principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
SysLog log = new SysLog();
// ##请求用户
log.setUserId(LoginUserUtil.getUserId());
// ##日志标题
log.setOperLocation(description);
// ##日志类型
log.setOper(String.valueOf(getControllerMethodInfo(joinPoint).get("type")));
// ##日志请求url
// log.setRequestUrl(request.getRequestURI());…
// ##请求方式
// log.setRequestType(request.getMethod());
// ##请求参数
log.setJson(logParams.toString());
// ##请求开始时间
long endTime = System.currentTimeMillis();
// ##请求耗时
Long logElapsedTime = endTime - beginTime;
log.setRunTime(logElapsedTime.intValue());
// ##调用线程保存至log表
executor.execute(new SaveSystemLogThread(log, sysLogService));
} catch (Exception e) {
log.error("AOP后置通知异常", e);
}
((ExecutorService) executor).shutdown();
}
/**
* 保存日志至数据库
*/
protected static class SaveSystemLogThread implements Runnable {
private SysLog log;
private ISysLogService logService;
public SaveSystemLogThread(SysLog esLog, ISysLogService logService) {
this.log = esLog;
this.logService = logService;
}
@Override
public void run() {
log.setId(String.valueOf(UUID.randomUUID()));
logService.save(log);
}
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
* @param joinPoint 切点
* @return 方法描述
* @throws Exception
*/
public static Map<String, Object> getControllerMethodInfo(JoinPoint joinPoint) throws Exception{
Map<String, Object> map = new HashMap<String, Object>(16);
// ## 获取目标类名
String targetName = joinPoint.getTarget().getClass().getName();
// ## 获取方法名
String methodName = joinPoint.getSignature().getName();
// ## 获取相关参数
Object[] arguments = joinPoint.getArgs();
// ## 生成类对象
Class targetClass = Class.forName(targetName);
// ## 获取该类中的方法
Method[] methods = targetClass.getMethods();
String description = "";
Integer type = null;
for(Method method : methods) {
if(!method.getName().equals(methodName)) {
continue;
}
Class[] clazzs = method.getParameterTypes();
if(clazzs.length != arguments.length) {
// ## 比较方法中参数个数与从切点中获取的参数个数是否相同,原因是方法可以重载
continue;
}
description = method.getAnnotation(EpcLog.class).description();
type = method.getAnnotation(EpcLog.class).businessType().ordinal();
map.put("description", description);
map.put("type", type);
}
return map;
}
}