这两天做了个系统日志管理功能,现在来总结一下。项目中用到AOP主要是将日志记录从业务逻辑代码中划分出来,减少冗余代码和重复工作步骤...废话有点多
首先创建操作系统日志表,表结构如下:
1.创建操作日志注解类Log.java
package com.daqing.financial.hrauth.annotation;
import com.daqing.financial.hrauth.enums.OperationType;
import com.daqing.financial.hrauth.enums.OperationUnit;
import java.lang.annotation.*;
/**
* @author Rogers
* 操作日志注解
* @create 2020-07-03
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 方法描述,可使用占位符获取参数:{
{tel}}
*/
String detail() default "";
/**
* 日志等级:自己定,此处分为1-9
*/
int level() default 0;
/**
* 操作类型(enum):主要是select,insert,update,delete
*/
OperationType operationType() default OperationType.UNKNOWN;
/**
* 被操作的对象(此处使用enum):可以是任何对象,如表名(user),或者是工具(redis)
*/
OperationUnit operationUnit() default OperationUnit.UNKNOWN;
}
2.创建切面类记录操作系统日志(此处的获取登录用户信息是根据request请求中的token获取到user_id,从而得到所有用户信息)
package com.daqing.financial.hrauth.aspect;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.daqing.financial.hrauth.annotation.Log;
import com.daqing.financial.hrauth.service.TokenService;
import com.daqing.financial.hrauth.service.UserLoginService;
import com.daqing.framework.domain.hrms.Token;
import com.daqing.framework.domain.hrms.UserEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName SysLogAspect
* @Description 操作日志切面
* @Date 2020/9/30
* @Version 1.0
*/
@Slf4j
@Aspect
@Component
public class SysLogAspect {
@Resource
private Operation operation;
@Autowired
private TokenService tokenService;
@Autowired
private UserLoginService userLoginService;
/**
* 此处的切点是注解的方式,也可以用包名的方式达到相同的效果
* '@Pointcut("execution(* com.wwj.springboot.service.impl.*.*(..))")'
*/
@Pointcut("@annotation(com.daqing.financial.hrauth.annotation.Log)")
public void operationLog() {
}
/**
* 环绕增强,相当于MethodInterceptor
*/
@Around("operationLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object res = null;
long time = System.currentTimeMillis();
try {
res = joinPoint.proceed();
time = System.currentTimeMillis() - time;
return res;
} finally {
try {
//User systemUser = (User) SecurityUtils.getSubject().getPrincipal();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("token");
Token userToken = tokenService.getOne(new QueryWrapper<Token>().eq("token", token));
UserEntity systemUser = userLoginService.getOne(new QueryWrapper<UserEntity>().eq("id",userToken.getUserId()));
operation.addOperationLog(joinPoint,res,time,systemUser);
//方法执行完成后增加日志
// addOperationLog(joinPoint, res, time);
} catch (Exception e) {
log.error("LogAspect 操作失败:" + e.getMessage());
e.printStackTrace();
}
}
}
/**
* 对当前登录用户和占位符处理
*
* @param argNames 方法参数名称数组
* @param args 方法参数数组
* @param annot