diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/logging/aspect/WhiteListLogAspect.java b/lms/nladmin-system/src/main/java/org/nl/modules/logging/aspect/WhiteListLogAspect.java new file mode 100644 index 000000000..ebe2c9c8a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/modules/logging/aspect/WhiteListLogAspect.java @@ -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 filterArgs(Object[] args) { + return Arrays.stream(args).filter(object -> !(object instanceof MultipartFilter) + && !(object instanceof HttpServletRequest) + && !(object instanceof HttpServletResponse) + ).collect(Collectors.toList()); + } +} + diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/logging/properties/LoggingProperties.java b/lms/nladmin-system/src/main/java/org/nl/modules/logging/properties/LoggingProperties.java new file mode 100644 index 000000000..ce11f37d3 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/modules/logging/properties/LoggingProperties.java @@ -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 includePaths; + + public List getIncludePaths() { + return includePaths; + } + + public void setIncludePaths(List includePaths) { + this.includePaths = includePaths; + } +} + + diff --git a/lms/nladmin-system/src/main/java/org/nl/system/service/logging/ISysInterfaceLogService.java b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/ISysInterfaceLogService.java new file mode 100644 index 000000000..937174ccf --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/ISysInterfaceLogService.java @@ -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; + +/** + *

+ * 系统日志表 服务类 + *

+ * + * @author author + * @since 2024-07-29 + */ +public interface ISysInterfaceLogService extends IService { + + @Async + void save(String username, String outParam, String browser, String ip, ProceedingJoinPoint joinPoint, SysInterfaceLog log); +} diff --git a/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/SysInterfaceLog.java b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/SysInterfaceLog.java new file mode 100644 index 000000000..769e3f81c --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/SysInterfaceLog.java @@ -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; + +/** + *

+ * 系统日志表 + *

+ * + * @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; + } + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.java b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.java new file mode 100644 index 000000000..656a5aa9c --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.java @@ -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; + +/** + *

+ * 系统日志表 Mapper 接口 + *

+ * + * @author author + * @since 2024-07-29 + */ +public interface SysInterfaceLogMapper extends BaseMapper { + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.xml b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.xml new file mode 100644 index 000000000..81fd0f0f2 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/dao/mapper/SysInterfaceLogMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/lms/nladmin-system/src/main/java/org/nl/system/service/logging/impl/SysInterfaceLogServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/impl/SysInterfaceLogServiceImpl.java new file mode 100644 index 000000000..4ce771974 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/system/service/logging/impl/SysInterfaceLogServiceImpl.java @@ -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; + +/** + *

+ * 系统日志表 服务实现类 + *

+ * + * @author author + * @since 2024-07-29 + */ +@Service +public class SysInterfaceLogServiceImpl extends ServiceImpl 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 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 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 filterArgs(Object[] args) { + return Arrays.stream(args).filter(object -> !(object instanceof MultipartFilter) + && !(object instanceof HttpServletRequest) + && !(object instanceof HttpServletResponse) + ).collect(Collectors.toList()); + } +} diff --git a/lms/nladmin-system/src/main/resources/config/application.yml b/lms/nladmin-system/src/main/resources/config/application.yml index 8d0fd7ace..ae1cbc24c 100644 --- a/lms/nladmin-system/src/main/resources/config/application.yml +++ b/lms/nladmin-system/src/main/resources/config/application.yml @@ -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: