package com.vincent.rsf.server.common.aspect;
|
|
import com.alibaba.fastjson.JSON;
|
import com.vincent.rsf.common.utils.Utils;
|
import com.vincent.rsf.framework.common.Cools;
|
import com.vincent.rsf.server.common.annotation.OperationLog;
|
import com.vincent.rsf.server.common.utils.IpTools;
|
import com.vincent.rsf.server.system.entity.OperationRecord;
|
import com.vincent.rsf.server.system.entity.User;
|
import com.vincent.rsf.server.system.service.OperationRecordService;
|
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.annotation.*;
|
import org.aspectj.lang.reflect.MethodSignature;
|
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
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.util.Collections;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 操作日志记录
|
*
|
* @author vincent
|
* @since 2020-03-21 16:58:16:05
|
*/
|
@Aspect
|
@Component
|
public class OperationLogAspect {
|
|
@Resource
|
private OperationRecordService operationRecordService;
|
// 参数、返回结果、错误信息等最大保存长度
|
private static final int MAX_LENGTH = 1000;
|
// 用于记录请求耗时
|
private final ThreadLocal<Long> startTime = new ThreadLocal<>();
|
|
@Pointcut("@annotation(com.vincent.rsf.server.common.annotation.OperationLog)")
|
public void operationLog() {
|
}
|
|
@Before("operationLog()")
|
public void doBefore(JoinPoint joinPoint) throws Throwable {
|
startTime.set(System.currentTimeMillis());
|
}
|
|
@AfterReturning(pointcut = "operationLog()", returning = "result")
|
public void doAfterReturning(JoinPoint joinPoint, Object result) {
|
saveLog(joinPoint, result, null);
|
}
|
|
@AfterThrowing(value = "operationLog()", throwing = "e")
|
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
|
saveLog(joinPoint, null, e);
|
}
|
|
/**
|
* 保存操作记录
|
*/
|
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;
|
}
|
OperationRecord record = new OperationRecord();
|
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));
|
}
|
operationRecordService.saveAsync(record);
|
}
|
|
/**
|
* 获取当前登录用户
|
*/
|
private User getLoginUser() {
|
Authentication subject = SecurityContextHolder.getContext().getAuthentication();
|
if (subject != null) {
|
Object object = subject.getPrincipal();
|
if (object instanceof User) {
|
return (User) object;
|
}
|
}
|
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;
|
}
|
|
/**
|
* 获取操作功能
|
*
|
* @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;
|
}
|
|
}
|