CREATE TABLE `my_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) DEFAULT NULL COMMENT '用户名',
`ip` varchar(255) DEFAULT NULL COMMENT '请求ip',
`description` varchar(255) DEFAULT NULL COMMENT '操作描述',
`params` text COMMENT '参数值',
`brower` varchar(255) DEFAULT NULL COMMENT '浏览器',
`time` bigint(20) DEFAULT NULL COMMENT '执行时间',
`type` varchar(255) DEFAULT NULL COMMENT '日志类型',
`method` varchar(255) DEFAULT NULL COMMENT '执行方法',
`result` text COMMENT '结果',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`exception_detail` text COMMENT '异常详细信息',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='这是一个测试表,可忽略';
只用来记录操作,例如查询操作,会记录查询的参数以及返回结果等。
大致思路:
1. 生成my_log表的pojo 实体类
2. 创建一个Aspect类。添加注解
@Component
@Aspect
3. 创建@interface 注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyLog {
//描述
String desc() default "";
}
4. 在自定义的Aspect类中添加 刚创建的注解,并添加
@Pointcut
5. 添加环绕注解。方法的内容为获取 插入my_log 表的字段值,然后使用mybtis插入数据库中。
/**
* 本类用于 在常规操作下生成日志记录,插入日志表
*/
@Component
@Aspect
@Slf4j
public class LogAspect {
@Resource
LogInfoMapper logInfoMapper;
ThreadLocal<Long> currentTime = new ThreadLocal<>();
/**
* 设置操作日志 切入点 ,记录操作日志 在注解的位置切入代码
*/
@Pointcut("@annotation(com.demo.annotation.MyLog)")
public void logPointCut(){
}
/**
* 设置环绕通知,使用 logPointCut()上注册的切入点
* @param joinPoint
* @return
*/
@Around("logPointCut()")
public Object saveOperationLog(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = RequestHolder.getHttpServletRequest();
long start = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
MyLog myLog = method.getAnnotation(MyLog.class);//获取 自定义的myLog注解
LogInfo operationLog = new LogInfo();
operationLog.setUserName(RequestContext.getCurrentUser().getUsername());
operationLog.setIp(LogUtils.getIp(request));
operationLog.setBrower(LogUtils.getBrowser(request));
String desc = myLog.desc();//获取方法的描述
operationLog.setDescription(desc);
String className = joinPoint.getTarget().getClass().getName();//类名
String methodName = method.getName();//方法名字
methodName = className +"."+methodName;
operationLog.setMethod(methodName);
StringBuilder params = new StringBuilder("{");
Object[] args = joinPoint.getArgs();//参数值
//参数名称
String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
if(args != null){
for (int i = 0; i < args.length; i++) {
params.append(" ").append(argNames[i]).append(": ").append(args[i]);
}
}
params.append("}");
operationLog.setParams(JSONObject.toJSONString(params.toString()));
Object result ;
try {
result = joinPoint.proceed();
operationLog.setResult(JSONObject.toJSONString(result));//结果
}catch (Exception exception) {
operationLog.setExceptionDetail(exception.getMessage());
throw exception;
} finally {
long end = System.currentTimeMillis();
long cost = (end - start);
operationLog.setTime(cost);
logInfoMapper.save(operationLog);
}
return result;
}
}
6. 在controller中使用
@PostMapping("/shortVoideIndex")
@ApiOperation("短视频列表")
@MyLog(desc = "短视频列表")
public JSONObject shortVoideIndex(HttpSession session, ShortVideoParams params) {
UserInfo user = RequestContext.getCurrentUser();
JSONObject res = new JSONObject();
Map<String, Object> stringObjectMap = infoDataShortVideoService.shortVoideIndex(params.getPageNo(), params.getPageSize(), params, user.getId());
res.put("totalNum", stringObjectMap.get("total"));
res.put("resultList", stringObjectMap.get("list"));
return res;
}