package com.gihon.component.web.aspect; import java.time.Duration; import java.time.LocalDateTime; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint; 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 org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import com.gihon.component.util.JacksonJsonUtils; import com.gihon.component.util.UUIDGenerater; import com.gihon.component.web.auth.AuthUtils; import lombok.extern.slf4j.Slf4j; /** * 通过切面 记录请求日志 * * @author baihe */ @Slf4j @Aspect @Component public class LogAspect { // private static String types = "java.lang.Integer,java.lang.Double,java.lang.Float,java.lang.Long,java.lang.Short,java.lang.Byte,java.lang.Boolean,java.lang.Char,java.lang.String,int,double,long,short,byte,boolean,char,float"; @Pointcut("@within(org.springframework.web.bind.annotation.RestController)") public void logPointAround() { } @Around("logPointAround()") public Object doAroundLog(ProceedingJoinPoint thisJoinPoint) throws Throwable { Object r = null; String method = thisJoinPoint.getSignature().getName(); LocalDateTime startTime = LocalDateTime.now(); String uuid = UUIDGenerater.genUUID(); String url = null; Long userId = null; Map param = null; boolean flag = false; try { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); userId = AuthUtils.getUserId(); url = request.getRequestURL().toString(); param = getArgs(thisJoinPoint, ((MethodSignature) thisJoinPoint.getSignature()).getParameterNames()); r = thisJoinPoint.proceed();// 被代理对象执行结果 } catch (Throwable e) { flag = true; throw e;// 异常信息有统一异常处理器处理 }finally { log.info("[访问地址:{}] [方法:{}] [uuid:{}] [执行时间:{}(豪秒)] [userId:{}] [参数:{}] [结果:{}]", url, (thisJoinPoint.getTarget().getClass().getSimpleName()+"."+method), uuid, Duration.between(startTime, LocalDateTime.now()).toMillis(),userId, param , flag ? "异常" : "正常"); } return r; } private Map getArgs(ProceedingJoinPoint joinPoint, String[] parameterNames) { Map allArgs = new HashMap<>(); Object[] args = joinPoint.getArgs(); for (int k = 0; k < args.length; k++) { Object arg = args[k]; if (arg == null) { continue; } if (arg instanceof ServletResponse || arg instanceof ServletRequest) {// continue; } else if (arg instanceof MultipartFile) {// 文件 allArgs.put(parameterNames[k], ((MultipartFile) arg).getOriginalFilename()); } else if (arg instanceof MultipartFile[]) {// 文件 allArgs.put(parameterNames[k], ((MultipartFile[]) arg).length); } else if (arg instanceof Number || arg instanceof String || arg instanceof Character || arg instanceof Boolean) {// 简单类型 allArgs.put(parameterNames[k], arg); } else if (arg instanceof Collection) {// 集合 allArgs.put(parameterNames[k], arg); } else if (arg.getClass().isArray()) {// 数组 allArgs.put(parameterNames[k], JacksonJsonUtils.readObject(JacksonJsonUtils.writeObject(arg),List.class)); } else {// 复杂类型 Map m = JacksonJsonUtils.convertToMap(arg); if (m != null) { allArgs.putAll(m); } } } return allArgs; } }