package com.order.erp.log; import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.order.erp.common.constant.Constant; import com.order.erp.common.utils.RequestHolder; import com.order.erp.common.utils.RequestStringUtils; import com.order.erp.common.utils.SecurityUtils; import com.order.erp.common.utils.ThrowableUtil; import com.order.erp.domain.dto.SysLogDO; import com.order.erp.service.SysLogService; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.time.LocalDateTime; /** * @date 2018-11-24 */ @Component @Aspect @Slf4j public class LogAspect { @Resource private SysLogService logService; ThreadLocal<Long> currentTime = new ThreadLocal<>(); /** * 配置切入点 */ @Pointcut("@annotation(com.order.erp.log.Log)") public void logPointcut() { // 该方法无方法体,主要为了让同类中其他方法使用此切入点 } /** * 配置环绕通知,使用在方法logPointcut()上注册的切入点 * * @param joinPoint join point for advice */ @Around("logPointcut()") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { Object result; currentTime.set(System.currentTimeMillis()); result = joinPoint.proceed(); logService.save(wrapperLog(joinPoint)); currentTime.remove(); return result; } /** * @param joinPoint * @return */ private SysLogDO wrapperLog(ProceedingJoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Log aopLog = method.getAnnotation(Log.class); // 方法路径 String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; StringBuilder params = new StringBuilder("{"); //参数值 Object[] argValues = joinPoint.getArgs(); //参数名称 String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); if (argValues != null) { for (int i = 0; i < argValues.length; i++) { params.append(" ").append(argNames[i]).append(": ").append(argValues[i]); } } HttpServletRequest request = RequestHolder.getHttpServletRequest(); SysLogDO sysLogDO = SysLogDO.builder() .logType("INFO") .time(System.currentTimeMillis() - currentTime.get()) .browser(RequestStringUtils.getBrowser(request)) .requestIp(RequestStringUtils.getIp(request)) .build(); // 描述 if (sysLogDO != null) { sysLogDO.setDescription(aopLog.value()); } assert sysLogDO != null; String loginPath = "login"; String userName = null; if (loginPath.equals(signature.getName())) { try { assert argValues != null; userName = new JSONObject(argValues[0]).get("userName").toString(); } catch (Exception e) { e.printStackTrace(); } } else { userName = getUsername(); } if (StringUtils.isBlank(userName)) { sysLogDO.setCreateTime(LocalDateTime.now()); sysLogDO.setCreateBy("system"); } else { sysLogDO.setCreateTime(LocalDateTime.now()); sysLogDO.setCreateBy(userName); } sysLogDO.setAddress(RequestStringUtils.getCityInfo(sysLogDO.getRequestIp())); sysLogDO.setMethod(methodName); sysLogDO.setUsername(userName); sysLogDO.setParams(params.toString() + " }"); sysLogDO.setEnableFlag(Constant.ENABLE_TEN); return sysLogDO; } /** * 配置异常通知 * * @param joinPoint join point for advice * @param e exception */ @AfterThrowing(pointcut = "logPointcut()", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { SysLogDO sysLogDO = wrapperLog((ProceedingJoinPoint) joinPoint); currentTime.remove(); sysLogDO.setExceptionDetail(String.valueOf(ThrowableUtil.getStackTrace(e).getBytes())); logService.save(sysLogDO); } /** * @return */ public String getUsername() { try { return SecurityUtils.getUsername(); } catch (Exception e) { return ""; } } }