refactor: 优化系统日志收集方式
This commit is contained in:
parent
103cb3e999
commit
2d7bbc53f9
|
@ -21,11 +21,11 @@ public @interface RequestLog {
|
||||||
String module() default OperationLogModule.UNKNOWN_MODULE;
|
String module() default OperationLogModule.UNKNOWN_MODULE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目
|
* 项目,系统模块没有项目id默认系统
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
String projectId() default "default";
|
String projectId() default "system";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作类型
|
* 操作类型
|
||||||
|
@ -61,11 +61,11 @@ public @interface RequestLog {
|
||||||
boolean isBatch() default false;
|
boolean isBatch() default false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作前触发内容
|
* 是否在业务代码执行前记录内容
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
String event() default "";
|
boolean isBefore() default false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传入执行类
|
* 传入执行类
|
||||||
|
|
|
@ -57,6 +57,11 @@ public class OperationLogAspect {
|
||||||
private OperationLogService operationLogService;
|
private OperationLogService operationLogService;
|
||||||
|
|
||||||
private ThreadLocal<List<OperationLog>> beforeValue = new ThreadLocal<>();
|
private ThreadLocal<List<OperationLog>> beforeValue = new ThreadLocal<>();
|
||||||
|
|
||||||
|
private ThreadLocal<String> treadLocalDetails = new ThreadLocal<>();
|
||||||
|
|
||||||
|
private ThreadLocal<String> treadLocalSourceId = new ThreadLocal<>();
|
||||||
|
|
||||||
private ThreadLocal<String> localUser = new ThreadLocal<>();
|
private ThreadLocal<String> localUser = new ThreadLocal<>();
|
||||||
|
|
||||||
private final String[] methodNames = new String[]{"delete", "update", "add"};
|
private final String[] methodNames = new String[]{"delete", "update", "add"};
|
||||||
|
@ -76,13 +81,14 @@ public class OperationLogAspect {
|
||||||
//获取切入点所在的方法
|
//获取切入点所在的方法
|
||||||
Method method = signature.getMethod();
|
Method method = signature.getMethod();
|
||||||
RequestLog msLog = method.getAnnotation(RequestLog.class);
|
RequestLog msLog = method.getAnnotation(RequestLog.class);
|
||||||
if (msLog != null && StringUtils.isNotEmpty(msLog.event())) {
|
if (msLog != null && msLog.isBefore()) {
|
||||||
//获取参数对象数组
|
//获取参数对象数组
|
||||||
Object[] args = joinPoint.getArgs();
|
Object[] args = joinPoint.getArgs();
|
||||||
//获取方法参数名
|
//获取方法参数名
|
||||||
String[] params = discoverer.getParameterNames(method);
|
String[] params = discoverer.getParameterNames(method);
|
||||||
//将参数纳入Spring管理
|
//将参数纳入Spring管理
|
||||||
EvaluationContext context = new StandardEvaluationContext();
|
EvaluationContext context = new StandardEvaluationContext();
|
||||||
|
|
||||||
for (int len = 0; len < params.length; len++) {
|
for (int len = 0; len < params.length; len++) {
|
||||||
context.setVariable(params[len], args[len]);
|
context.setVariable(params[len], args[len]);
|
||||||
}
|
}
|
||||||
|
@ -95,11 +101,13 @@ public class OperationLogAspect {
|
||||||
context.setVariable("msClass", applicationContext.getBean(clazz));
|
context.setVariable("msClass", applicationContext.getBean(clazz));
|
||||||
isNext = true;
|
isNext = true;
|
||||||
}
|
}
|
||||||
if (isNext) {
|
if (!isNext) {
|
||||||
Expression expression = parser.parseExpression(msLog.event());
|
return;
|
||||||
List<OperationLog> beforeContent = expression.getValue(context, List.class);
|
|
||||||
beforeValue.set(beforeContent);
|
|
||||||
}
|
}
|
||||||
|
// 初始化details内容
|
||||||
|
initDetails(msLog, context);
|
||||||
|
// 初始化资源id
|
||||||
|
initResourceId(msLog, context);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtils.error("操作日志写入异常:" + joinPoint.getSignature());
|
LogUtils.error("操作日志写入异常:" + joinPoint.getSignature());
|
||||||
|
@ -111,6 +119,65 @@ public class OperationLogAspect {
|
||||||
.anyMatch(input -> input.contains(keyword));
|
.anyMatch(input -> input.contains(keyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initDetails(RequestLog msLog, EvaluationContext context) {
|
||||||
|
try {
|
||||||
|
// 批量内容处理
|
||||||
|
if (StringUtils.isNotBlank(msLog.details()) && msLog.details().startsWith("#msClass")) {
|
||||||
|
if (msLog.isBatch()) {
|
||||||
|
Expression expression = parser.parseExpression(msLog.details());
|
||||||
|
List<OperationLog> beforeContent = expression.getValue(context, List.class);
|
||||||
|
beforeValue.set(beforeContent);
|
||||||
|
} else {
|
||||||
|
Expression detailsEx = parser.parseExpression(msLog.details());
|
||||||
|
String details = detailsEx.getValue(context, String.class);
|
||||||
|
this.treadLocalDetails.set(details);
|
||||||
|
}
|
||||||
|
} else if (StringUtils.isNotBlank(msLog.details()) && msLog.details().startsWith("#")) {
|
||||||
|
Expression titleExp = parser.parseExpression(msLog.details());
|
||||||
|
String details = titleExp.getValue(context, String.class);
|
||||||
|
this.treadLocalDetails.set(details);
|
||||||
|
} else {
|
||||||
|
this.treadLocalDetails.set(msLog.details());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error("未获取到details内容", e);
|
||||||
|
this.treadLocalDetails.set(msLog.details());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initResourceId(RequestLog msLog, EvaluationContext context) {
|
||||||
|
try {
|
||||||
|
// 批量内容处理
|
||||||
|
if (StringUtils.isNotBlank(msLog.sourceId()) && msLog.sourceId().startsWith("#msClass")) {
|
||||||
|
Expression detailsEx = parser.parseExpression(msLog.sourceId());
|
||||||
|
String sourceId = detailsEx.getValue(context, String.class);
|
||||||
|
treadLocalSourceId.set(sourceId);
|
||||||
|
} else if (StringUtils.isNotBlank(msLog.sourceId()) && msLog.sourceId().startsWith("#")) {
|
||||||
|
Expression titleExp = parser.parseExpression(msLog.sourceId());
|
||||||
|
String sourceId = titleExp.getValue(context, String.class);
|
||||||
|
treadLocalSourceId.set(sourceId);
|
||||||
|
} else {
|
||||||
|
treadLocalSourceId.set(msLog.sourceId());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error("未获取到资源id", e);
|
||||||
|
treadLocalSourceId.set(msLog.sourceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProjectId(RequestLog msLog, EvaluationContext context) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotBlank(msLog.projectId()) && msLog.projectId().startsWith("#")) {
|
||||||
|
Expression titleExp = parser.parseExpression(msLog.projectId());
|
||||||
|
return titleExp.getValue(context, String.class);
|
||||||
|
} else {
|
||||||
|
return msLog.projectId();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return msLog.projectId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void add(OperationLog operationLog, RequestLog msLog, JoinPoint joinPoint, Object result) {
|
private void add(OperationLog operationLog, RequestLog msLog, JoinPoint joinPoint, Object result) {
|
||||||
//从切面织入点处通过反射机制获取织入点处的方法
|
//从切面织入点处通过反射机制获取织入点处的方法
|
||||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
@ -143,38 +210,23 @@ public class OperationLogAspect {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 项目ID表达式
|
// 项目ID表达式
|
||||||
try {
|
operationLog.setProjectId(getProjectId(msLog, context));
|
||||||
Expression titleExp = parser.parseExpression(msLog.projectId());
|
|
||||||
String project = titleExp.getValue(context, String.class);
|
if (!msLog.isBefore()) {
|
||||||
operationLog.setProjectId(project);
|
// 初始化资源id
|
||||||
} catch (Exception e) {
|
initResourceId(msLog, context);
|
||||||
operationLog.setProjectId(msLog.projectId());
|
// 初始化内容详情
|
||||||
}
|
initDetails(msLog, context);
|
||||||
// 标题
|
|
||||||
if (StringUtils.isNotEmpty(msLog.details())) {
|
|
||||||
String details = msLog.details();
|
|
||||||
try {
|
|
||||||
Expression titleExp = parser.parseExpression(details);
|
|
||||||
details = titleExp.getValue(context, String.class);
|
|
||||||
operationLog.setDetails(details);
|
|
||||||
} catch (Exception e) {
|
|
||||||
operationLog.setDetails(details);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 资源ID
|
|
||||||
if (StringUtils.isNotEmpty(msLog.sourceId())) {
|
|
||||||
try {
|
|
||||||
String sourceId = msLog.sourceId();
|
|
||||||
Expression titleExp = parser.parseExpression(sourceId);
|
|
||||||
sourceId = titleExp.getValue(context, String.class);
|
|
||||||
operationLog.setSourceId(sourceId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
operationLog.setSourceId(msLog.sourceId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 内容详情
|
||||||
|
operationLog.setDetails(treadLocalDetails.get());
|
||||||
|
// 资源id
|
||||||
|
operationLog.setSourceId(treadLocalSourceId.get());
|
||||||
|
|
||||||
if (StringUtils.isBlank(operationLog.getCreateUser())) {
|
if (StringUtils.isBlank(operationLog.getCreateUser())) {
|
||||||
operationLog.setCreateUser(localUser.get());
|
operationLog.setCreateUser(localUser.get());
|
||||||
}
|
}
|
||||||
|
// 从返回内容中获取资源id
|
||||||
if (StringUtils.isEmpty(operationLog.getSourceId()) && !msLog.isBatch()) {
|
if (StringUtils.isEmpty(operationLog.getSourceId()) && !msLog.isBatch()) {
|
||||||
operationLog.setSourceId(getId(result));
|
operationLog.setSourceId(getId(result));
|
||||||
}
|
}
|
||||||
|
@ -217,11 +269,8 @@ public class OperationLogAspect {
|
||||||
operationLog.setMethod(StringUtils.join(className, ".", method.getName()));
|
operationLog.setMethod(StringUtils.join(className, ".", method.getName()));
|
||||||
operationLog.setCreateTime(System.currentTimeMillis());
|
operationLog.setCreateTime(System.currentTimeMillis());
|
||||||
operationLog.setCreateUser(SessionUtils.getUserId());
|
operationLog.setCreateUser(SessionUtils.getUserId());
|
||||||
HttpServletRequest request = ((ServletRequestAttributes)
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
RequestContextHolder.getRequestAttributes()).getRequest();
|
operationLog.setPath(request.getServletPath());
|
||||||
String path = request.getServletPath();
|
|
||||||
operationLog.setPath(path);
|
|
||||||
|
|
||||||
// 获取操作
|
// 获取操作
|
||||||
RequestLog msLog = method.getAnnotation(RequestLog.class);
|
RequestLog msLog = method.getAnnotation(RequestLog.class);
|
||||||
if (msLog != null) {
|
if (msLog != null) {
|
||||||
|
@ -236,6 +285,7 @@ public class OperationLogAspect {
|
||||||
} finally {
|
} finally {
|
||||||
localUser.remove();
|
localUser.remove();
|
||||||
beforeValue.remove();
|
beforeValue.remove();
|
||||||
|
treadLocalDetails.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ public class OperationLogService {
|
||||||
log.setCreateUser("admin");
|
log.setCreateUser("admin");
|
||||||
}
|
}
|
||||||
// 限制长度
|
// 限制长度
|
||||||
if (StringUtils.isNotBlank(log.getDetails()) && log.getDetails().length() > 1000) {
|
if (StringUtils.isNotBlank(log.getDetails()) && log.getDetails().length() > 500) {
|
||||||
log.setDetails(log.getDetails().substring(0, 1000));
|
log.setDetails(log.getDetails().substring(0, 499));
|
||||||
}
|
}
|
||||||
operationLogMapper.insert(log);
|
operationLogMapper.insert(log);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,10 @@ public class OperationLogService {
|
||||||
OperationLogMapper logMapper = sqlSession.getMapper(OperationLogMapper.class);
|
OperationLogMapper logMapper = sqlSession.getMapper(OperationLogMapper.class);
|
||||||
if (CollectionUtils.isNotEmpty(logs)) {
|
if (CollectionUtils.isNotEmpty(logs)) {
|
||||||
logs.forEach(item -> {
|
logs.forEach(item -> {
|
||||||
|
// 限制长度
|
||||||
|
if (StringUtils.isNotBlank(item.getDetails()) && item.getDetails().length() > 500) {
|
||||||
|
item.setDetails(item.getDetails().substring(0, 499));
|
||||||
|
}
|
||||||
logMapper.insert(item);
|
logMapper.insert(item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,7 @@ public class ApiDefinitionController {
|
||||||
|
|
||||||
@PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE)
|
@PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_ADD_API)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_ADD_API)
|
||||||
@RequestLog(type = OperationLogType.ADD, module = OperationLogModule.API_DEFINITION,
|
@RequestLog(type = OperationLogType.ADD, module = OperationLogModule.API_DEFINITION, projectId = "#request.projectId", details = "#request.name")
|
||||||
sourceId = "#request.id", projectId = "#request.projectId", details = "#request.name")
|
|
||||||
public ApiDefinitionDTO add(@Validated({Created.class}) @RequestBody ApiDefinitionDTO request,
|
public ApiDefinitionDTO add(@Validated({Created.class}) @RequestBody ApiDefinitionDTO request,
|
||||||
@RequestParam(value = "files") List<MultipartFile> bodyFiles) {
|
@RequestParam(value = "files") List<MultipartFile> bodyFiles) {
|
||||||
return apiDefinitionService.create(request, bodyFiles);
|
return apiDefinitionService.create(request, bodyFiles);
|
||||||
|
@ -41,7 +40,7 @@ public class ApiDefinitionController {
|
||||||
|
|
||||||
@PostMapping(value = "/batch-del")
|
@PostMapping(value = "/batch-del")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ_DELETE)
|
||||||
@RequestLog(isBatch = true, event = "#msClass.getLogs(#ids)", msClass = ApiDefinitionService.class)
|
@RequestLog(isBatch = true, isBefore = true, details = "#msClass.getLogs(#ids)", msClass = ApiDefinitionService.class)
|
||||||
public void batchDelete(@RequestBody List<String> ids) {
|
public void batchDelete(@RequestBody List<String> ids) {
|
||||||
apiDefinitionService.batchDelete(ids);
|
apiDefinitionService.batchDelete(ids);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue