diff --git a/virtual-patient-common/pom.xml b/virtual-patient-common/pom.xml index 9b7c105e..f666a501 100644 --- a/virtual-patient-common/pom.xml +++ b/virtual-patient-common/pom.xml @@ -30,6 +30,12 @@ + + + org.springframework.boot + spring-boot-starter-aop + + org.springframework.boot spring-boot-starter-undertow diff --git a/virtual-patient-common/src/main/java/com/supervision/config/RequestLogConfig.java b/virtual-patient-common/src/main/java/com/supervision/config/RequestLogConfig.java new file mode 100644 index 00000000..ab337d89 --- /dev/null +++ b/virtual-patient-common/src/main/java/com/supervision/config/RequestLogConfig.java @@ -0,0 +1,151 @@ +package com.supervision.config; + +import cn.hutool.json.JSONUtil; +import lombok.Data; +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 org.springframework.util.ObjectUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +/** + * 日志切面 + * + * @author :liu + * create :2020-11-16 10:50 + **/ +@Component +@Aspect +@Slf4j +public class RequestLogConfig { + + + @SuppressWarnings("all") + @Around("within(com..*..controller..*) && @within(org.springframework.web.bind.annotation.RestController)") + public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + long start = System.currentTimeMillis(); + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + Object result = proceedingJoinPoint.proceed(); + RequestInfo requestInfo = new RequestInfo(); + requestInfo.setUrl(request.getRequestURL().toString()); + requestInfo.setHttpMethod(request.getMethod()); + requestInfo.setClassMethod(String.format("%s.%s", proceedingJoinPoint.getSignature().getDeclaringTypeName(), + proceedingJoinPoint.getSignature().getName())); + requestInfo.setRequestParams(getRequestParamsByProceedingJoinPoint(proceedingJoinPoint)); + requestInfo.setResult(proceedResult(result)); + requestInfo.setTimeCost(System.currentTimeMillis() - start); + log.info("Request Info: {}", JSONUtil.toJsonStr(requestInfo)); + return result; + } + + private String proceedResult(Object result) { + String value = String.valueOf(result); + if (value.length() > 10240){ + value = value.substring(0, 1024) + "......" + value.substring(value.length() - 1024); + return value; + } + return value; + } + + + @SuppressWarnings("all") + @AfterThrowing(pointcut = "@within(org.springframework.web.bind.annotation.RestController)", throwing = "e") + public void doAfterThrow(JoinPoint joinPoint, RuntimeException e) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + RequestErrorInfo requestErrorInfo = new RequestErrorInfo(); + requestErrorInfo.setUrl(request.getRequestURL().toString()); + requestErrorInfo.setHttpMethod(request.getMethod()); + requestErrorInfo.setClassMethod(String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName(), + joinPoint.getSignature().getName())); + requestErrorInfo.setRequestParams(getRequestParamsByJoinPoint(joinPoint)); + requestErrorInfo.setException(e); + log.info("Error Request Info : {}", JSONUtil.toJsonStr(requestErrorInfo)); + } + + /** + * 获取入参 + * + * @param proceedingJoinPoint + * @return + */ + private Map getRequestParamsByProceedingJoinPoint(ProceedingJoinPoint proceedingJoinPoint) { + //参数名 + String[] paramNames = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames(); + //参数值 + Object[] paramValues = proceedingJoinPoint.getArgs(); + + return buildRequestParam(paramNames, paramValues); + } + + private Map getRequestParamsByJoinPoint(JoinPoint joinPoint) { + //参数名 + String[] paramNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); + //参数值 + Object[] paramValues = joinPoint.getArgs(); + + return buildRequestParam(paramNames, paramValues); + } + + private Map buildRequestParam(String[] paramNames, Object[] paramValues) { + Map requestParams = new HashMap<>(); + for (int i = 0; i < paramNames.length; i++) { + Object value = paramValues[i]; + if (value instanceof ServletRequest || value instanceof ServletResponse) { + //ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false) + //ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response + continue; + } + + //如果是文件对象 + if (value instanceof MultipartFile) { + MultipartFile file = (MultipartFile) value; + //获取文件名 + value = file.getOriginalFilename(); + } else if (value instanceof String) { + // 如果参数很长,就对参数进行修剪 + String temp = (String) value; + if (!ObjectUtils.isEmpty(temp) && temp.length() > 1024) { + value = temp.substring(0, 10) + "......" + temp.substring(temp.length() - 10); + } + } + requestParams.put(paramNames[i], value); + } + + return requestParams; + } + + @Data + public static class RequestInfo { + private String url; + private String httpMethod; + private String classMethod; + private Object requestParams; + private Object result; + private Long timeCost; + } + + @Data + public static class RequestErrorInfo { + private String url; + private String httpMethod; + private String classMethod; + private Object requestParams; + private RuntimeException exception; + } +}