package com.vincent.rsf.openApi.aspect;
|
|
import com.alibaba.fastjson.JSON;
|
import com.vincent.rsf.common.utils.Utils;
|
import com.vincent.rsf.framework.common.Cools;
|
import com.vincent.rsf.openApi.annotation.OperationLog;
|
import com.vincent.rsf.openApi.entity.app.ApiForeignLog;
|
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
|
import com.vincent.rsf.openApi.service.ApiForeignLogService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.aspectj.lang.JoinPoint;
|
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.core.annotation.Order;
|
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 javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.lang.reflect.Method;
|
import java.rmi.NoSuchObjectException;
|
import java.util.*;
|
|
/**
|
* Created by Administrator on 2019-07-09.
|
*/
|
@Component
|
@Aspect
|
@Slf4j
|
@Order(2)
|
public class LogAspect {
|
|
// 参数、返回结果、错误信息等最大保存长度
|
private static final int MAX_LENGTH = 1000;
|
// 用于记录请求耗时
|
private final ThreadLocal<Long> startTime = new ThreadLocal<>();
|
|
@Resource
|
private ApiForeignLogService apiForeignLogService;
|
|
public LogAspect() {
|
}
|
|
/**
|
* 切入点
|
* 匹配controller包及其所有子包下的所有类的所有方法
|
*/
|
@Pointcut("execution(* com.vincent.rsf.openApi.controller..*.*(..))")
|
public void controllerPc() {
|
}
|
|
/**
|
* 环绕通知
|
* @param pjp ProceedingJoinPoint
|
* @return 方法结果
|
*/
|
@Around("controllerPc()")
|
public Object around(ProceedingJoinPoint pjp) {
|
String methodName = pjp.getSignature().getName();
|
try {
|
ServletRequestAttributes attributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
.orElseThrow(() -> new NoSuchObjectException("前置通知中获取的 ServletRequestAttributes 对象为空"));
|
HttpServletRequest request = attributes.getRequest();
|
|
// if("getToken".equals(methodName) || "getToken".equals(methodName))
|
// return pjp.proceed();
|
|
// 前置通知
|
log.info("------【前置通知】------");
|
|
// 记录请求内容
|
log.info("浏览器输入的网址:{}", request.getRequestURL().toString());
|
log.info("HTTP_METHOD:{}", request.getMethod());
|
log.info("IP:{}", request.getRemoteAddr());
|
log.info("执行的业务方法名:{}", pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName());
|
log.info("业务方法获得的参数:{}", Arrays.toString(pjp.getArgs()));
|
|
Object result = pjp.proceed();
|
|
// 后置通知
|
log.info("------【后置通知】------");
|
log.info("{}方法的返回值:{}", pjp.getSignature().getName(), result);
|
|
saveLog1(pjp, result, null);
|
return result;
|
} catch (Throwable e) {
|
// 异常通知
|
log.error("------【异常通知】------");
|
log.error("{}方法异常,参数:{},异常:", pjp.getSignature().getName(), Arrays.toString(pjp.getArgs()), e);
|
|
saveLog1(pjp, null, (Exception) e);
|
return CommonResponse.error("服务器处理数据异常");
|
} finally {
|
// 最终通知
|
if(!methodName.isEmpty() && !"getRegistered".equals(methodName)){
|
log.info("------【最终通知】------");
|
log.info("{}方法执行结束", pjp.getSignature().getName());
|
}
|
}
|
}
|
|
private void saveLog1(JoinPoint joinPoint, Object result, Exception e) {
|
|
ApiForeignLog record = new ApiForeignLog();
|
Long endTime = startTime.get();
|
record.setCreateTime(new Date());
|
// 记录操作耗时
|
if (endTime != null) {
|
record.setSpendTime((int) (System.currentTimeMillis() - endTime));
|
}
|
record.setTimestamp(String.valueOf(endTime));
|
// // 记录当前登录用户id、租户id
|
// User user = getLoginUser();
|
// if (user != null) {
|
// record.setUserId(user.getId());
|
// record.setTenantId(user.getTenantId());
|
// }
|
// 记录请求地址、请求方式、ip
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
HttpServletRequest request = (attributes == null ? null : attributes.getRequest());
|
if (request != null) {
|
record.setUrl(request.getRequestURI());
|
// record.setClientIp(IpTools.gainRealIp(request));
|
}
|
// 记录异常信息
|
if (e != null) {
|
record.setResult(0);
|
record.setErr(Utils.sub(e.toString(), MAX_LENGTH));
|
} else {
|
record.setResult(1);
|
}
|
// // 记录操作功能
|
// record.setNamespace(desc);
|
// // 记录备注
|
// if (!Cools.isEmpty(ol.comments())) {
|
// record.setMemo(ol.comments());
|
// }
|
// 记录请求参数
|
record.setRequest(Utils.sub(Arrays.toString(joinPoint.getArgs()), MAX_LENGTH));
|
record.setResponse(Utils.sub(JSON.toJSONString(result), MAX_LENGTH));
|
|
apiForeignLogService.saveAsync(record);
|
}
|
|
/**
|
* 保存操作记录
|
*/
|
private void saveLog(JoinPoint joinPoint, Object result, Exception e) {
|
// 记录模块名、操作功能、请求方法、请求参数、返回结果
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
Method method = signature.getMethod();
|
if (null == method) {
|
return;
|
}
|
OperationLog ol = method.getAnnotation(OperationLog.class);
|
if (null == ol) {
|
return;
|
}
|
String desc = getDescription(method, ol);
|
if (Cools.isEmpty(desc)) {
|
return;
|
}
|
|
ApiForeignLog record = new ApiForeignLog();
|
Long endTime = startTime.get();
|
record.setCreateTime(new Date());
|
// 记录操作耗时
|
if (endTime != null) {
|
record.setSpendTime((int) (System.currentTimeMillis() - endTime));
|
}
|
record.setTimestamp(String.valueOf(endTime));
|
// // 记录当前登录用户id、租户id
|
// User user = getLoginUser();
|
// if (user != null) {
|
// record.setUserId(user.getId());
|
// record.setTenantId(user.getTenantId());
|
// }
|
// 记录请求地址、请求方式、ip
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
HttpServletRequest request = (attributes == null ? null : attributes.getRequest());
|
if (request != null) {
|
record.setUrl(request.getRequestURI());
|
// record.setClientIp(IpTools.gainRealIp(request));
|
}
|
// 记录异常信息
|
if (e != null) {
|
record.setResult(0);
|
record.setErr(Utils.sub(e.toString(), MAX_LENGTH));
|
} else {
|
record.setResult(1);
|
}
|
// 记录操作功能
|
record.setNamespace(desc);
|
// 记录备注
|
if (!Cools.isEmpty(ol.comments())) {
|
record.setMemo(ol.comments());
|
}
|
// 记录请求参数
|
if (ol.param() && request != null) {
|
record.setRequest(Utils.sub(getParams(joinPoint, request), MAX_LENGTH));
|
}
|
// 记录请求结果
|
if (ol.result() && result != null) {
|
record.setResponse(Utils.sub(JSON.toJSONString(result), MAX_LENGTH));
|
}
|
apiForeignLogService.saveAsync(record);
|
}
|
|
/**
|
* 获取操作功能
|
*
|
* @param method Method
|
* @param ol OperationLog
|
* @return String
|
*/
|
private String getDescription(Method method, OperationLog ol) {
|
if (!Cools.isEmpty(ol.value())) {
|
return ol.value();
|
}
|
return null;
|
}
|
|
/**
|
* 获取请求参数
|
*
|
* @param joinPoint JoinPoint
|
* @param request HttpServletRequest
|
* @return String
|
*/
|
private String getParams(JoinPoint joinPoint, HttpServletRequest request) {
|
String params;
|
|
Map<String, String> paramsMap = new HashMap<>();
|
|
Map<String, String[]> map = Collections.unmodifiableMap(request.getParameterMap());
|
for (Map.Entry<String, String[]> entry : map.entrySet()) {
|
paramsMap.put(entry.getKey(), Utils.join(entry.getValue(), ","));
|
}
|
|
if (paramsMap.keySet().size() > 0) {
|
params = JSON.toJSONString(paramsMap);
|
} else {
|
StringBuilder sb = new StringBuilder();
|
for (Object arg : joinPoint.getArgs()) {
|
if (null == arg
|
|| arg instanceof MultipartFile
|
|| arg instanceof HttpServletRequest
|
|| arg instanceof HttpServletResponse) {
|
continue;
|
}
|
sb.append(JSON.toJSONString(arg)).append(" ");
|
}
|
params = sb.toString();
|
}
|
return params;
|
}
|
|
}
|