fix:AOP添加接口日志
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package org.nl.modules.logging.aspect;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.nl.common.utils.SecurityUtils;
|
||||
import org.nl.modules.common.utils.RequestHolder;
|
||||
import org.nl.modules.common.utils.StringUtils;
|
||||
import org.nl.modules.common.utils.ThrowableUtil;
|
||||
import org.nl.modules.logging.properties.LoggingProperties;
|
||||
import org.nl.system.service.logging.ISysInterfaceLogService;
|
||||
import org.nl.system.service.logging.dao.SysInterfaceLog;
|
||||
import org.nl.system.service.logging.dao.SysLog;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.support.MultipartFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author by: zz
|
||||
* @ClassName: WhiteListLogAspect
|
||||
* @Description: 外部接口日志切面插入日志表
|
||||
* @Date: 2024/7/25 15:06
|
||||
*/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class WhiteListLogAspect {
|
||||
|
||||
@Autowired
|
||||
private LoggingProperties loggingProperties;
|
||||
|
||||
@Autowired
|
||||
private ISysInterfaceLogService interfaceLogService;
|
||||
|
||||
private AntPathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
@Pointcut("execution(* org.nl.wms.ext..*Service.*(..))")
|
||||
public void logPointcut() {
|
||||
// 该方法无方法体,主要为了让同类中其他方法使用此切入点
|
||||
}
|
||||
|
||||
@Around("logPointcut()")
|
||||
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
Object[] args = joinPoint.getArgs();
|
||||
Object result = null;
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
result = joinPoint.proceed(args);
|
||||
long endTime = System.currentTimeMillis();
|
||||
long time = endTime - startTime;
|
||||
addLog(joinPoint, JSONUtil.toJsonStr(result), time);
|
||||
} catch (Exception e) {
|
||||
log.error("doAround日志记录异常,异常信息为:", e);
|
||||
throw e;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志记录操作
|
||||
*/
|
||||
public void addLog(ProceedingJoinPoint joinPoint, String outParams, long time) {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
HttpServletResponse response = attributes.getResponse();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
// 方法路径
|
||||
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||
String[] split = joinPoint.getTarget().getClass().getName().split("\\.");
|
||||
String className = split[split.length - 1];
|
||||
StringUtils.getIp(request);
|
||||
log.info("\n\r=======================================\n\r" +
|
||||
"请求地址:{} \n\r" +
|
||||
"请求方式:{} \n\r" +
|
||||
"请求类方法:{} \n\r" +
|
||||
"方法名::{} \n\r" +
|
||||
"调用IP::{} \n\r" +
|
||||
"接口名称:{} \n\r" +
|
||||
"请求方法参数:{} \n\r" +
|
||||
"返回报文:{} \n\r" +
|
||||
"处理耗时:{} ms \n\r" +
|
||||
"=======================================\n\r",
|
||||
request.getRequestURI(),
|
||||
request.getMethod(),
|
||||
joinPoint.getSignature(),
|
||||
className,
|
||||
StringUtils.getIp(request),
|
||||
signature.getName(),
|
||||
JSONUtil.toJsonStr(filterArgs(joinPoint.getArgs())),
|
||||
outParams,
|
||||
time
|
||||
);
|
||||
SysInterfaceLog log = new SysInterfaceLog("INFO", time);
|
||||
|
||||
interfaceLogService.save(getUsername(), outParams, StringUtils.getBrowser(request), StringUtils.getIp(request), joinPoint, log);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
try {
|
||||
return SecurityUtils.getCurrentUsername();
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
|
||||
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
|
||||
SysInterfaceLog log = new SysInterfaceLog("ERROR", 0L);
|
||||
log.setException_detail(ThrowableUtil.getStackTrace(e).getBytes());
|
||||
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||
interfaceLogService.save(getUsername(), e.toString(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint) joinPoint, log);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤参数
|
||||
*
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
private List<Object> filterArgs(Object[] args) {
|
||||
return Arrays.stream(args).filter(object -> !(object instanceof MultipartFilter)
|
||||
&& !(object instanceof HttpServletRequest)
|
||||
&& !(object instanceof HttpServletResponse)
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.nl.modules.logging.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "logging")
|
||||
public class LoggingProperties {
|
||||
private List<String> includePaths;
|
||||
|
||||
public List<String> getIncludePaths() {
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
public void setIncludePaths(List<String> includePaths) {
|
||||
this.includePaths = includePaths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.nl.system.service.logging;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.nl.system.service.logging.dao.SysInterfaceLog;
|
||||
import org.nl.system.service.logging.dao.SysLog;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统日志表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2024-07-29
|
||||
*/
|
||||
public interface ISysInterfaceLogService extends IService<SysInterfaceLog> {
|
||||
|
||||
@Async
|
||||
void save(String username, String outParam, String browser, String ip, ProceedingJoinPoint joinPoint, SysInterfaceLog log);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.nl.system.service.logging.dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统日志表
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2024-07-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@NoArgsConstructor
|
||||
@TableName("sys_interface_log")
|
||||
public class SysInterfaceLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 标识
|
||||
*/
|
||||
@TableId(value = "log_id")
|
||||
private String log_id;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private String log_type;
|
||||
|
||||
/**
|
||||
* 日志类别
|
||||
*/
|
||||
private String log_dtl_info;
|
||||
|
||||
/**
|
||||
* 日志级别
|
||||
*/
|
||||
private String log_level;
|
||||
|
||||
/**
|
||||
* 方法
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 请求ip
|
||||
*/
|
||||
private String request_ip;
|
||||
|
||||
/**
|
||||
* 时间
|
||||
*/
|
||||
private Long time;
|
||||
|
||||
/**
|
||||
* 用户名字
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 浏览器
|
||||
*/
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 返回结果
|
||||
*/
|
||||
private String return_result;
|
||||
|
||||
/**
|
||||
* 异常明细
|
||||
*/
|
||||
private byte[] exception_detail;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private String create_time;
|
||||
|
||||
public SysInterfaceLog(String logType, Long time) {
|
||||
this.log_type = logType;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.nl.system.service.logging.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.nl.system.service.logging.dao.SysInterfaceLog;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统日志表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2024-07-29
|
||||
*/
|
||||
public interface SysInterfaceLogMapper extends BaseMapper<SysInterfaceLog> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.system.service.logging.dao.mapper.SysInterfaceLogMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.nl.system.service.logging.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.nl.modules.common.utils.StringUtils;
|
||||
import org.nl.modules.logging.annotation.Log;
|
||||
import org.nl.system.service.logging.ISysInterfaceLogService;
|
||||
import org.nl.system.service.logging.dao.SysInterfaceLog;
|
||||
import org.nl.system.service.logging.dao.SysLog;
|
||||
import org.nl.system.service.logging.dao.mapper.SysInterfaceLogMapper;
|
||||
import org.nl.system.service.logging.dao.mapper.SysLogMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.support.MultipartFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统日志表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2024-07-29
|
||||
*/
|
||||
@Service
|
||||
public class SysInterfaceLogServiceImpl extends ServiceImpl<SysInterfaceLogMapper, SysInterfaceLog> implements ISysInterfaceLogService {
|
||||
@Override
|
||||
public void save(String username, String outParam, String browser, String ip, ProceedingJoinPoint joinPoint, SysInterfaceLog logDto) {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
|
||||
String[] split = joinPoint.getTarget().getClass().getName().split("\\.");
|
||||
String className = split[split.length - 1];
|
||||
|
||||
assert logDto != null;
|
||||
logDto.setRequest_ip(ip);
|
||||
|
||||
logDto.setAddress(StringUtils.getCityInfo(logDto.getRequest_ip()));
|
||||
logDto.setMethod(signature.getName());
|
||||
logDto.setUsername(username);
|
||||
logDto.setParams(JSONUtil.toJsonStr(filterArgs(joinPoint.getArgs())).replace("\\",""));
|
||||
logDto.setBrowser(browser);
|
||||
logDto.setReturn_result(outParam);
|
||||
logDto.setLog_dtl_info(className);
|
||||
logDto.setLog_id(IdUtil.getSnowflake(1, 1).nextIdStr());
|
||||
logDto.setCreate_time(DateUtil.now());
|
||||
this.save(logDto);
|
||||
}
|
||||
|
||||
private String getParameter(Method method, Object[] args) {
|
||||
List<Object> argList = new ArrayList<>();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
//将RequestBody注解修饰的参数作为请求参数
|
||||
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
|
||||
if (requestBody != null) {
|
||||
argList.add(args[i]);
|
||||
}
|
||||
//将RequestParam注解修饰的参数作为请求参数
|
||||
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
|
||||
if (requestParam != null) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
String key = parameters[i].getName();
|
||||
if (!StrUtil.isEmpty(requestParam.value())) {
|
||||
key = requestParam.value();
|
||||
}
|
||||
map.put(key, args[i]);
|
||||
argList.add(map);
|
||||
}
|
||||
}
|
||||
if (argList.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList);
|
||||
}
|
||||
|
||||
private List<Object> filterArgs(Object[] args) {
|
||||
return Arrays.stream(args).filter(object -> !(object instanceof MultipartFilter)
|
||||
&& !(object instanceof HttpServletRequest)
|
||||
&& !(object instanceof HttpServletResponse)
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ spring:
|
||||
jobStore:
|
||||
threadPool:
|
||||
threadCount: 14
|
||||
# class: org.nl.system.service.quartz.SimpleThreadPool
|
||||
# class: org.nl.system.service.quartz.SimpleThreadPool
|
||||
scheduler-name: quartzScheduler
|
||||
task:
|
||||
pool:
|
||||
@@ -92,6 +92,11 @@ logging:
|
||||
file:
|
||||
path: d:\log\lms
|
||||
config: classpath:logback-spring.xml
|
||||
include-paths:
|
||||
- /api/mes/**
|
||||
- /api/lms/**
|
||||
- /api/sap/**
|
||||
- /api/crm/**
|
||||
# sa-token白名单配置
|
||||
security:
|
||||
# 排除路径
|
||||
@@ -151,7 +156,7 @@ sa-token:
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: false
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
mapper-locations:
|
||||
- classpath:org.nl.**.mapper/*.xml
|
||||
global-config:
|
||||
|
||||
Reference in New Issue
Block a user