perf: 优化日志保留与分页查询
- 降低普通只读请求的日志写入并保留敏感 GET 审计 - 增加数据库分批清理、时间索引和文件滚动容量上限 - 增加近 30 天筛选、稳定倒序和分页大小限制
This commit is contained in:
@@ -26,7 +26,9 @@ import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 记录管理端 Controller 操作结果及最小必要请求摘要。
|
||||
@@ -43,20 +45,38 @@ public class LogAspect {
|
||||
private static final String SKILL_API_PREFIX = "/api/v1/skill";
|
||||
private static final List<String> SKILL_IDENTIFIER_KEYS =
|
||||
List.of("id", "resourceId", "skillId", "sourceId");
|
||||
private static final Set<String> READ_ONLY_HTTP_METHODS =
|
||||
Set.of("GET", "HEAD", "OPTIONS");
|
||||
|
||||
private final WriteLogMapper logService;
|
||||
private final LogRecordProperties config;
|
||||
|
||||
/**
|
||||
* 创建操作日志切面。
|
||||
*
|
||||
* @param logService 操作日志写入 Mapper
|
||||
* @param config 操作日志配置
|
||||
*/
|
||||
public LogAspect(WriteLogMapper logService, LogRecordProperties config) {
|
||||
this.logService = logService;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配管理端控制器与通用增删改查控制器方法。
|
||||
*/
|
||||
@Pointcut("within(@org.springframework.web.bind.annotation.RestController *) " +
|
||||
"|| execution(* tech.easyflow.common.web.controller.BaseCurdController.*(..))")
|
||||
public void pointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行业务方法并按配置持久化操作日志。
|
||||
*
|
||||
* @param proceedingJoinPoint 当前连接点
|
||||
* @return 业务方法返回值
|
||||
* @throws Throwable 业务方法或日志写入异常
|
||||
*/
|
||||
@Around("pointcut()")
|
||||
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
@@ -72,6 +92,10 @@ public class LogAspect {
|
||||
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
|
||||
Class<?> controllerClass = signature.getDeclaringType();
|
||||
Method method = signature.getMethod();
|
||||
LogRecord logRecord = method.getAnnotation(LogRecord.class);
|
||||
if (!shouldRecordRequest(request, logRecord)) {
|
||||
return proceedingJoinPoint.proceed();
|
||||
}
|
||||
String params = getRequestParamsString(request);
|
||||
Throwable actionFailure = null;
|
||||
|
||||
@@ -82,7 +106,6 @@ public class LogAspect {
|
||||
throw throwable;
|
||||
} finally {
|
||||
WriteLog sysLog = new WriteLog();
|
||||
LogRecord logRecord = method.getAnnotation(LogRecord.class);
|
||||
if (StpUtil.isLogin()) {
|
||||
|
||||
BigInteger accountId = SaTokenUtil.getLoginAccount().getId();
|
||||
@@ -103,6 +126,22 @@ public class LogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前请求是否需要写入操作日志。
|
||||
*
|
||||
* @param request 当前 HTTP 请求
|
||||
* @param logRecord 方法上的显式日志标记
|
||||
* @return 需要记录返回 {@code true}
|
||||
*/
|
||||
private boolean shouldRecordRequest(HttpServletRequest request, LogRecord logRecord) {
|
||||
if (config.isRecordReadActions() || logRecord != null) {
|
||||
return true;
|
||||
}
|
||||
String httpMethod = request.getMethod();
|
||||
return httpMethod == null
|
||||
|| !READ_ONLY_HTTP_METHODS.contains(httpMethod.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* 持久化操作日志;业务动作已失败时,日志异常不得覆盖原始异常。
|
||||
*
|
||||
@@ -123,6 +162,13 @@ public class LogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析日志动作名称。
|
||||
*
|
||||
* @param logRecord 显式日志标记
|
||||
* @param method 当前控制器方法
|
||||
* @return 日志动作名称
|
||||
*/
|
||||
private String buildActionName(LogRecord logRecord, Method method) {
|
||||
if (logRecord != null && StringUtil.hasText(logRecord.value())) {
|
||||
return logRecord.value();
|
||||
@@ -199,6 +245,12 @@ public class LogAspect {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取并限制请求查询参数,避免超长内容进入数据库。
|
||||
*
|
||||
* @param request 当前 HTTP 请求
|
||||
* @return 有界查询参数文本
|
||||
*/
|
||||
private String getRequestParamsString(HttpServletRequest request) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Enumeration<String> e = request.getParameterNames();
|
||||
|
||||
Reference in New Issue
Block a user