自定义日志开发
场景:如果项目中的一些修改记录比较重要,需要记录下来,可以直接自定义日志的开发。
自定义注解类
@Target(ElementType.METHOD)//作用于方法上
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
@Documented//标记注解
public @interface MyLog {
/**
* 用户操作哪个模块
*/
String title() default "";
/**
* 记录用户操作的动作
*/
String action() default "";
}
配置织入点(以上面自定义注解为表示)
/**
* 配置织入点(以@MyLog注解为标志)
* 只要出现 @MyLog注解都会进入
*/
@Pointcut("@annotation(com.example.secondhandmall.aop.annotation.MyLog)")
public void logPointCut(){
log.debug("logPointCut");
}
环绕增强
/**
* 环绕增强
* @param point
* @return
* @throws Throwable
*/
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
MDC.put("TRACE_ID", UUID.randomUUID().toString());
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
try {
// TODO 暂时不写日志
saveSysLog(point, time);
} catch (Exception e) {
log.error("e={}",e);
}
// 正常请求到这里结束清除请求链路信息
MDC.remove("TRACE_ID");
return result;
}
保存日志
**
* 把日志保存
* @Author: liuxl
* @UpdateUser:
* @Version: 0.0.1
* @param joinPoint
* @param time
* @return void
* @throws
*/
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = new SysLog();
MyLog myLog = method.getAnnotation(MyLog.class);
if(myLog != null){
//注解上的描述
sysLog.setOperation(myLog.title()+"-"+myLog.action());
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
//打印该方法耗时时间
log.info("请求{}.{}耗时{}毫秒",className,methodName,time);
Object[] args = joinPoint.getArgs();
String params=null;
try {
//请求的参数
if(args.length!=0){
params= JSON.toJSONString(args);
}
} catch (Exception e) {
params = Arrays.toString(args);
}
sysLog.setParams(params);
//获取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//设置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
log.info("Ip{},接口地址{},请求方式{},入参:{}",sysLog.getIp(),request.getRequestURL(),request.getMethod(),sysLog.getParams());
//用户名
String token = request.getHeader(Constant.ACCESS_TOKEN);
if(null == token && null !=request.getParameterMap() && null != request.getParameterMap().get(Constant.ACCESS_TOKEN)){
// 尝试从url取一下token
token = request.getParameterMap().get(Constant.ACCESS_TOKEN)[0];
}
String userId= JwtTokenUtil.getUserId(token);
String username= JwtTokenUtil.getUserName(token);
sysLog.setUsername(username);
sysLog.setUserId(userId);
sysLog.setTime((int) time);
sysLog.setId(UUID.randomUUID().toString());
sysLog.setCreateTime(new Date());
log.info(sysLog.toString());
sysLogMapper.insertSelective(sysLog);
}
合体
@Aspect
@Component
@Slf4j
public class SysLogAspect {
//环绕增强
@Autowired
private SysLogMapper sysLogMapper;
/**
* 配置织入点(以@MyLog注解为标志)
* 只要出现 @MyLog注解都会进入
*/
@Pointcut("@annotation(com.example.secondhandmall.aop.annotation.MyLog)")
public void logPointCut(){
log.debug("logPointCut");
}
/**
* 环绕增强
* @param point
* @return
* @throws Throwable
*/
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
MDC.put("TRACE_ID", UUID.randomUUID().toString());
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
try {
// TODO 暂时不写日志
saveSysLog(point, time);
} catch (Exception e) {
log.error("e={}",e);
}
// 正常请求到这里结束清除请求链路信息
MDC.remove("TRACE_ID");
return result;
}
/**
* 把日志保存
* @Author:
* @UpdateUser:
* @Version: 0.0.1
* @param joinPoint
* @param time
* @return void
* @throws
*/
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = new SysLog();
MyLog myLog = method.getAnnotation(MyLog.class);
if(myLog != null){
//注解上的描述
sysLog.setOperation(myLog.title()+"-"+myLog.action());
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
//打印该方法耗时时间
log.info("请求{}.{}耗时{}毫秒",className,methodName,time);
Object[] args = joinPoint.getArgs();
String params=null;
try {
//请求的参数
if(args.length!=0){
params= JSON.toJSONString(args);
}
} catch (Exception e) {
params = Arrays.toString(args);
}
sysLog.setParams(params);
//获取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//设置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
log.info("Ip{},接口地址{},请求方式{},入参:{}",sysLog.getIp(),request.getRequestURL(),request.getMethod(),sysLog.getParams());
//用户名
String token = request.getHeader(Constant.ACCESS_TOKEN);
if(null == token && null !=request.getParameterMap() && null != request.getParameterMap().get(Constant.ACCESS_TOKEN)){
// 尝试从url取一下token
token = request.getParameterMap().get(Constant.ACCESS_TOKEN)[0];
}
String userId= JwtTokenUtil.getUserId(token);
String username= JwtTokenUtil.getUserName(token);
sysLog.setUsername(username);
sysLog.setUserId(userId);
sysLog.setTime((int) time);
sysLog.setId(UUID.randomUUID().toString());
sysLog.setCreateTime(new Date());
log.info(sysLog.toString());
sysLogMapper.insertSelective(sysLog);
}
}