diff --git a/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogAspect.java b/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogAspect.java
index f53943e..666ea64 100644
--- a/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogAspect.java
+++ b/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogAspect.java
@@ -27,10 +27,14 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
- * 统一打印日志(支持忽略此aop, 采用@IgnoreRequestLog注解)
+ * 统一打印日志(支持忽略此aop, 采用@IgnoreRequestLog注解)
+ * @Deprecated 改类不会处理 @RequestMapping没有在controller上定义的情况。
+ * 建议使用{@link RequestLogV2Aspect}
+ * @see RequestLogV2Aspect
**/
@Aspect
@Slf4j
+@Deprecated
public class RequestLogAspect {
private final static Integer DEFAULT_LOG_SIZE = 2048;
private Integer logSize;
diff --git a/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogV2Aspect.java b/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogV2Aspect.java
new file mode 100644
index 0000000..d90fda4
--- /dev/null
+++ b/web-support-lib/src/main/java/cn/axzo/foundation/web/support/log/RequestLogV2Aspect.java
@@ -0,0 +1,144 @@
+package cn.axzo.foundation.web.support.log;
+
+import cn.axzo.foundation.exception.BusinessException;
+import cn.axzo.foundation.result.ApiResult;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableSet;
+import lombok.Builder;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.RestController;
+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.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 统一打印日志(支持忽略此aop, 采用@IgnoreRequestLog注解)
+ **/
+@Aspect
+@Slf4j
+public class RequestLogV2Aspect {
+ private final static Integer DEFAULT_LOG_SIZE = 2048;
+ private Integer logSize;
+
+ @Builder
+ public RequestLogV2Aspect(Integer logSize) {
+ this.logSize = Optional.ofNullable(logSize).orElse(DEFAULT_LOG_SIZE);
+ }
+
+ private static Set> EXCLUDE_CLASSES = ImmutableSet.of(ServletRequest.class, ServletResponse.class,
+ MultipartFile.class, BindingResult.class);
+
+ @Around("@within(restController)||@annotation(restController)")
+ public Object doAround(ProceedingJoinPoint joinPoint, RestController restController) throws Throwable {
+ //避免拦截非http请求. 如feign
+ if (RequestContextHolder.getRequestAttributes() == null) {
+ return joinPoint.proceed();
+ }
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ if (request != null) {
+ //用于在AbstractExceptionHandler中为dumpRequest, AbstractExceptionHandler无法直接获取body
+ request.setAttribute("params", this.getUserArgs(joinPoint.getArgs()));
+ }
+
+ IgnoreRequestLog annotation = AnnotationUtils.findAnnotation(((MethodSignature) joinPoint.getSignature()).getMethod(),
+ IgnoreRequestLog.class);
+
+ // 获取注解中的ignoreTypes
+ ImmutableSet ignoreTypes = Optional.ofNullable(annotation)
+ .map(a -> ImmutableSet.copyOf(a.types())).orElse(ImmutableSet.of());
+
+ Stopwatch stopwatch = Stopwatch.createStarted();
+ String requestLog = buildRequestLog(joinPoint, ignoreTypes);
+
+ String userSession = StringUtils.EMPTY;
+ String employeeSession = StringUtils.EMPTY;
+
+ String appClient = StringUtils.EMPTY;
+
+
+ Object proceed;
+ try {
+ proceed = joinPoint.proceed(joinPoint.getArgs());
+ } catch (BusinessException e) {
+ //stein会收集error级别的异常并告警. 对BizException. 不期望收到告警邮件. 因此将BizException对应的日志级别调整为warn
+ log.warn("api log, process error, caught BizException, url = {}, params = {}, userSession = {}, employeeSession = {}, appClient = {}, time cost = {} ms, BizException:",
+ request.getRequestURI(), requestLog, userSession, employeeSession, appClient, stopwatch.elapsed(TimeUnit.MILLISECONDS), e);
+ throw e;
+ } catch (Exception e) {
+ log.error("api log, process error, uncaught exception, url = {}, params = {}, userSession = {}, employeeSession = {}, appClient = {}, time cost = {} ms, exception:",
+ request.getRequestURI(), requestLog, userSession, employeeSession, appClient, stopwatch.elapsed(TimeUnit.MILLISECONDS), e);
+ throw e;
+ } catch (Error error) {
+ log.error("api log, process error, uncaught error, url = {}, params = {}, userSession = {}, employeeSession = {}, appClient = {}, time cost = {} ms, error:",
+ request.getRequestURI(), requestLog, userSession, employeeSession, appClient, stopwatch.elapsed(TimeUnit.MILLISECONDS), error);
+ throw error;
+ }
+
+ // 如果该接口定义的类型不是SILENT的, 则打印日志
+ if (!ignoreTypes.contains(IgnoreRequestLog.IgnoreType.ALL)) {
+ String responseLog;
+ try {
+ responseLog = buildResponseLog(proceed, ignoreTypes);
+ } catch (Exception ex) {
+ log.error("api log, process error, resp serialize error, url = {}, params = {}, userSession = {}, employeeSession = {}, appClient = {}, time cost = {} ms, error:",
+ request.getRequestURI(), requestLog, userSession, employeeSession, appClient, stopwatch.elapsed(TimeUnit.MILLISECONDS), ex);
+ throw ex;
+ }
+ log.info("api log, url = {}, params = {}, userSession = {}, employeeSession = {}, appClient = {}, result = {}, time cost = {} ms",
+ request.getRequestURI(),
+ StringUtils.left(requestLog, logSize),
+ userSession,
+ employeeSession,
+ appClient,
+ responseLog,
+ stopwatch.elapsed(TimeUnit.MILLISECONDS));
+ }
+
+ return proceed;
+ }
+
+ private String buildRequestLog(ProceedingJoinPoint joinPoint, Set ignoreTypes) {
+ if (ignoreTypes.contains(IgnoreRequestLog.IgnoreType.REQUEST)) {
+ return "IGNORED";
+ }
+ return JSONObject.toJSONString(this.getUserArgs(joinPoint.getArgs()));
+ }
+
+ private String buildResponseLog(Object proceed, Set ignoreTypes) {
+ if (proceed == null || !(ApiResult.class.isAssignableFrom(proceed.getClass()))) {
+ return StringUtils.EMPTY;
+ }
+ if (ignoreTypes.contains(IgnoreRequestLog.IgnoreType.RESPONSE)) {
+ return "IGNORED";
+ }
+ return StringUtils.left(JSONObject.toJSONString(proceed), logSize);
+ }
+
+ protected List