mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 10:57:13 +08:00 
			
		
		
		
	新增:新增系统监控/操作日志功能,优化日志表结构
This commit is contained in:
		| @@ -22,14 +22,14 @@ import lombok.RequiredArgsConstructor; | ||||
| import com.baomidou.mybatisplus.annotation.IEnum; | ||||
| 
 | ||||
| /** | ||||
|  * 操作结果枚举 | ||||
|  * 操作状态枚举 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2022/12/25 9:09 | ||||
|  */ | ||||
| @Getter | ||||
| @RequiredArgsConstructor | ||||
| public enum LogResultEnum implements IEnum<Integer> { | ||||
| public enum LogStatusEnum implements IEnum<Integer> { | ||||
| 
 | ||||
|     /** 成功 */ | ||||
|     SUCCESS(1, "成功"), | ||||
| @@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
|  | ||||
| import org.springframework.core.Ordered; | ||||
| import org.springframework.lang.NonNull; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.web.filter.OncePerRequestFilter; | ||||
| import org.springframework.web.util.ContentCachingRequestWrapper; | ||||
| @@ -32,7 +33,7 @@ import org.springframework.web.util.ContentCachingResponseWrapper; | ||||
| import org.springframework.web.util.WebUtils; | ||||
|  | ||||
| /** | ||||
|  * 操作日志过滤器(缓存请求和响应体过滤器) | ||||
|  * 系统日志过滤器(缓存请求和响应体过滤器) | ||||
|  * | ||||
|  * <p> | ||||
|  * 由于 requestBody 和 responseBody 分别对应的是 InputStream 和 OutputStream,由于流的特性,读取完之后就无法再被使用了。 所以,需要额外缓存一次流信息。 | ||||
| @@ -50,8 +51,8 @@ public class LogFilter extends OncePerRequestFilter implements Ordered { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) | ||||
|         throws ServletException, IOException { | ||||
|     protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, | ||||
|         @NonNull FilterChain filterChain) throws ServletException, IOException { | ||||
|         // 包装流,可重复读取 | ||||
|         if (!(request instanceof ContentCachingRequestWrapper)) { | ||||
|             request = new ContentCachingRequestWrapper(request); | ||||
|   | ||||
| @@ -52,7 +52,7 @@ import top.charles7c.cnadmin.common.util.helper.LoginHelper; | ||||
| import top.charles7c.cnadmin.common.util.holder.LogContextHolder; | ||||
| import top.charles7c.cnadmin.monitor.annotation.Log; | ||||
| import top.charles7c.cnadmin.monitor.config.properties.LogProperties; | ||||
| import top.charles7c.cnadmin.monitor.enums.LogResultEnum; | ||||
| import top.charles7c.cnadmin.monitor.enums.LogStatusEnum; | ||||
| import top.charles7c.cnadmin.monitor.model.entity.SysLog; | ||||
|  | ||||
| /** | ||||
| @@ -73,7 +73,7 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|     public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, | ||||
|         @NonNull Object handler) { | ||||
|         if (checkIsNeedRecord(handler, request)) { | ||||
|             // 记录操作时间 | ||||
|             // 记录时间 | ||||
|             this.logCreateTime(); | ||||
|         } | ||||
|         return true; | ||||
| @@ -100,7 +100,7 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 记录操作时间 | ||||
|      * 记录时间 | ||||
|      */ | ||||
|     private void logCreateTime() { | ||||
|         LogContext logContext = new LogContext(); | ||||
| @@ -121,12 +121,12 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|             SysLog sysLog = new SysLog(); | ||||
|             sysLog.setCreateTime(logContext.getCreateTime()); | ||||
|             sysLog.setElapsedTime(System.currentTimeMillis() - LocalDateTimeUtil.toEpochMilli(sysLog.getCreateTime())); | ||||
|             sysLog.setResult(LogResultEnum.SUCCESS); | ||||
|             sysLog.setStatus(LogStatusEnum.SUCCESS); | ||||
|  | ||||
|             // 记录异常信息 | ||||
|             Exception exception = logContext.getException(); | ||||
|             if (exception != null) { | ||||
|                 sysLog.setResult(LogResultEnum.FAILURE); | ||||
|                 sysLog.setStatus(LogStatusEnum.FAILURE); | ||||
|                 sysLog.setException(ExceptionUtil.stacktraceToString(exception, -1)); | ||||
|             } | ||||
|             return sysLog; | ||||
| @@ -175,8 +175,8 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|             sysLog.setRequestBody(this.desensitize( | ||||
|                 JSONUtil.isTypeJSON(requestBody) ? JSONUtil.parseObj(requestBody) : ServletUtil.getParamMap(request))); | ||||
|         } | ||||
|         sysLog.setRequestIp(ServletUtil.getClientIP(request)); | ||||
|         sysLog.setLocation(IpUtils.getCityInfo(sysLog.getRequestIp())); | ||||
|         sysLog.setClientIp(ServletUtil.getClientIP(request)); | ||||
|         sysLog.setLocation(IpUtils.getCityInfo(sysLog.getClientIp())); | ||||
|         sysLog.setBrowser(ServletUtils.getBrowser(request)); | ||||
|         sysLog.setCreateUser(sysLog.getCreateUser() == null ? LoginHelper.getUserId() : sysLog.getCreateUser()); | ||||
|     } | ||||
| @@ -199,7 +199,7 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|             sysLog.setResponseBody(responseBody); | ||||
|         } | ||||
|         // 操作失败:>= 400 | ||||
|         sysLog.setResult(status >= HttpStatus.HTTP_BAD_REQUEST ? LogResultEnum.FAILURE : sysLog.getResult()); | ||||
|         sysLog.setStatus(status >= HttpStatus.HTTP_BAD_REQUEST ? LogStatusEnum.FAILURE : sysLog.getStatus()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -265,9 +265,9 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|      * 检查是否要记录系统日志 | ||||
|      * | ||||
|      * @param handler | ||||
|      *            / | ||||
|      *            处理器 | ||||
|      * @param request | ||||
|      *            / | ||||
|      *            请求对象 | ||||
|      * @return true 需要记录,false 不需要记录 | ||||
|      */ | ||||
|     private boolean checkIsNeedRecord(Object handler, HttpServletRequest request) { | ||||
|   | ||||
| @@ -24,7 +24,7 @@ import lombok.Data; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
|  | ||||
| import top.charles7c.cnadmin.monitor.enums.LogResultEnum; | ||||
| import top.charles7c.cnadmin.monitor.enums.LogStatusEnum; | ||||
|  | ||||
| /** | ||||
|  * 系统日志实体 | ||||
| @@ -90,17 +90,17 @@ public class SysLog implements Serializable { | ||||
|     private Long elapsedTime; | ||||
|  | ||||
|     /** | ||||
|      * 操作结果(1成功 2失败) | ||||
|      * 操作状态(1成功 2失败) | ||||
|      */ | ||||
|     private LogResultEnum result; | ||||
|     private LogStatusEnum status; | ||||
|  | ||||
|     /** | ||||
|      * 操作IP | ||||
|      * 客户端IP | ||||
|      */ | ||||
|     private String requestIp; | ||||
|     private String clientIp; | ||||
|  | ||||
|     /** | ||||
|      * 操作地点 | ||||
|      * IP归属地 | ||||
|      */ | ||||
|     private String location; | ||||
|  | ||||
| @@ -115,12 +115,12 @@ public class SysLog implements Serializable { | ||||
|     private String exception; | ||||
|  | ||||
|     /** | ||||
|      * 操作人 | ||||
|      * 创建人 | ||||
|      */ | ||||
|     private Long createUser; | ||||
|  | ||||
|     /** | ||||
|      * 操作时间 | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     private LocalDateTime createTime; | ||||
| } | ||||
|   | ||||
| @@ -19,12 +19,15 @@ package top.charles7c.cnadmin.monitor.model.query; | ||||
| import static top.charles7c.cnadmin.common.annotation.Query.Type; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import org.springdoc.api.annotations.ParameterObject; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.annotation.Query; | ||||
|  | ||||
| @@ -47,4 +50,26 @@ public class OperationLogQuery implements Serializable { | ||||
|     @Schema(description = "操作人") | ||||
|     @Query(property = "createUser", type = Type.EQUAL) | ||||
|     private Long uid; | ||||
|  | ||||
|     /** | ||||
|      * 操作内容 | ||||
|      */ | ||||
|     @Schema(description = "操作内容") | ||||
|     @Query(type = Type.INNER_LIKE) | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 操作状态(1成功 2失败) | ||||
|      */ | ||||
|     @Schema(description = "操作状态(1成功 2失败)") | ||||
|     @Query(type = Type.EQUAL) | ||||
|     private Integer status; | ||||
|  | ||||
|     /** | ||||
|      * 操作时间 | ||||
|      */ | ||||
|     @Schema(description = "操作时间") | ||||
|     @Query(type = Type.BETWEEN) | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private List<Date> createTime; | ||||
| } | ||||
|   | ||||
| @@ -25,7 +25,7 @@ import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
|  | ||||
| import top.charles7c.cnadmin.monitor.enums.LogResultEnum; | ||||
| import top.charles7c.cnadmin.monitor.enums.LogStatusEnum; | ||||
|  | ||||
| /** | ||||
|  * 操作日志信息 | ||||
| @@ -52,16 +52,16 @@ public class OperationLogVO implements Serializable { | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 操作结果(1成功 2失败) | ||||
|      * 操作状态(1成功 2失败) | ||||
|      */ | ||||
|     @Schema(description = "操作结果(1成功 2失败)", type = "Integer", allowableValues = {"1", "2"}) | ||||
|     private LogResultEnum result; | ||||
|     @Schema(description = "操作状态(1成功 2失败)", type = "Integer", allowableValues = {"1", "2"}) | ||||
|     private LogStatusEnum status; | ||||
|  | ||||
|     /** | ||||
|      * 操作IP | ||||
|      */ | ||||
|     @Schema(description = "操作IP") | ||||
|     private String requestIp; | ||||
|     private String clientIp; | ||||
|  | ||||
|     /** | ||||
|      * 操作地点 | ||||
|   | ||||
| @@ -69,7 +69,14 @@ public class OperationLogServiceImpl implements OperationLogService { | ||||
|         // 分页查询 | ||||
|         IPage<SysLog> page = logMapper.selectPage(pageQuery.toPage(), queryWrapper); | ||||
|         PageInfo<OperationLogVO> pageInfo = PageInfo.build(page, OperationLogVO.class); | ||||
|         pageInfo.getList().forEach(this::fill); | ||||
|  | ||||
|         // 填充数据(如果是查询个人操作日志,只查询一次用户信息即可) | ||||
|         if (query.getUid() != null) { | ||||
|             SysUser sysUser = userMapper.selectById(query.getUid()); | ||||
|             pageInfo.getList().forEach(o -> o.setCreateUserString(sysUser.getUsername())); | ||||
|         } else { | ||||
|             pageInfo.getList().forEach(this::fill); | ||||
|         } | ||||
|         return pageInfo; | ||||
|     } | ||||
|  | ||||
| @@ -85,6 +92,6 @@ public class OperationLogServiceImpl implements OperationLogService { | ||||
|             return; | ||||
|         } | ||||
|         SysUser sysUser = userMapper.selectById(createUser); | ||||
|         vo.setCreateUserString(sysUser.getNickname()); | ||||
|         vo.setCreateUserString(sysUser.getUsername()); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user