java系统操作日志_SpringBoot自定义注解+AOP实现系统操作日志

package com.liuyanzhao.sens.aop;

import com.liuyanzhao.sens.annotation.SystemLog;

import com.liuyanzhao.sens.entity.Log;

import com.liuyanzhao.sens.entity.User;

import com.liuyanzhao.sens.enums.LogType;

import com.liuyanzhao.sens.service.LogService;

import com.liuyanzhao.sens.service.UserService;

import com.liuyanzhao.sens.utils.IpInfoUtil;

import com.liuyanzhao.sens.utils.ObjectUtil;

import com.liuyanzhao.sens.utils.ThreadPoolUtil;

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.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.checkerframework.checker.units.qual.A;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.core.NamedThreadLocal;

import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import java.lang.reflect.Method;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import java.util.Objects;

/**

* Spring AOP实现日志管理

*

* @author liuyanzhao

*/

@Aspect

@Component

@Slf4j

public class SystemLogAspect {

private static final ThreadLocal beginTimeThreadLocal = new NamedThreadLocal("ThreadLocal beginTime");

@Autowired

private LogService logService;

@Autowired

private UserService userService;

@Autowired

private IpInfoUtil ipInfoUtil;

@Autowired(required = false)

private HttpServletRequest request;

/**

* Controller层切点,注解方式

*/

//@Pointcut("execution(* *..controller..*Controller*.*(..))")

@Pointcut("@annotation(com.liuyanzhao.sens.annotation.SystemLog)")

public void controllerAspect() {

}

/**

* 前置通知 (在方法执行之前返回)用于拦截Controller层记录用户的操作的开始时间

*

* @param joinPoint 切点

* @throws InterruptedException

*/

@Before("controllerAspect()")

public void doBefore(JoinPoint joinPoint) throws InterruptedException {

//线程绑定变量(该数据只有当前请求的线程可见)

Date beginTime = new Date();

beginTimeThreadLocal.set(beginTime);

}

/**

* 后置通知(在方法执行之后并返回数据) 用于拦截Controller层无异常的操作

*

* @param joinPoint 切点

*/

@AfterReturning("controllerAspect()")

public void after(JoinPoint joinPoint) {

try {

String username = "";

String description = getControllerMethodInfo(joinPoint).get("description").toString();

Map requestParams = request.getParameterMap();

Log log = new Log();

//请求用户

//后台操作(非登录)

if (Objects.equals(getControllerMethodInfo(joinPoint).get("type"), 0)) {

//后台操作请求(已登录)

User user = userService.getLoginUser(request);

if (user != null) {

username = user.getUsername();

}

log.setUsername(username);

}

//日志标题

log.setName(description);

//日志类型

log.setLogType((int) getControllerMethodInfo(joinPoint).get("type"));

//日志请求url

log.setRequestUrl(request.getRequestURI());

//请求方式

log.setRequestType(request.getMethod());

//请求参数

log.setRequestParam(ObjectUtil.mapToString(requestParams));

//其他属性

log.setIp(ipInfoUtil.getIpAddr(request));

log.setCreateBy("system");

log.setUpdateBy("system");

log.setCreateTime(new Date());

log.setUpdateTime(new Date());

log.setDelFlag(0);

//.......

//请求开始时间

long beginTime = beginTimeThreadLocal.get().getTime();

long endTime = System.currentTimeMillis();

//请求耗时

Long logElapsedTime = endTime - beginTime;

log.setCostTime(logElapsedTime.intValue());

//持久化(存储到数据或者ES,可以考虑用线程池)

//logService.insert(log);

ThreadPoolUtil.getPool().execute(new SaveSystemLogThread(log, logService));

} catch (Exception e) {

log.error("AOP后置通知异常", e);

}

}

/**

* 保存日志至数据库

*/

private static class SaveSystemLogThread implements Runnable {

private Log log;

private LogService logService;

public SaveSystemLogThread(Log esLog, LogService logService) {

this.log = esLog;

this.logService = logService;

}

@Override

public void run() {

logService.insert(log);

}

}

/**

* 获取注解中对方法的描述信息 用于Controller层注解

*

* @param joinPoint 切点

* @return 方法描述

* @throws Exception

*/

public static Map getControllerMethodInfo(JoinPoint joinPoint) throws Exception {

Map map = new HashMap(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(SystemLog.class).description();

type = method.getAnnotation(SystemLog.class).type().ordinal();

map.put("description", description);

map.put("type", type);

}

return map;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值