mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	新增:新增系统监控/系统日志功能,优化日志表结构
This commit is contained in:
		| @@ -175,7 +175,7 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|         sysLog.setRequestUrl(StrUtil.isBlank(request.getQueryString()) ? request.getRequestURL().toString() | ||||
|             : request.getRequestURL().append("?").append(request.getQueryString()).toString()); | ||||
|         sysLog.setRequestMethod(request.getMethod()); | ||||
|         sysLog.setRequestHeader(this.desensitize(ServletUtil.getHeaderMap(request))); | ||||
|         sysLog.setRequestHeaders(this.desensitize(ServletUtil.getHeaderMap(request))); | ||||
|         String requestBody = this.getRequestBody(request); | ||||
|         if (StrUtil.isNotBlank(requestBody)) { | ||||
|             sysLog.setRequestBody(this.desensitize( | ||||
| @@ -198,7 +198,7 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|     private void logResponse(SysLog sysLog, HttpServletResponse response) { | ||||
|         int status = response.getStatus(); | ||||
|         sysLog.setStatusCode(status); | ||||
|         sysLog.setResponseHeader(this.desensitize(ServletUtil.getHeadersMap(response))); | ||||
|         sysLog.setResponseHeaders(this.desensitize(ServletUtil.getHeadersMap(response))); | ||||
|         // 响应体(不记录非 JSON 响应数据) | ||||
|         String responseBody = this.getResponseBody(response); | ||||
|         if (StrUtil.isNotBlank(responseBody) && JSONUtil.isTypeJSON(responseBody)) { | ||||
|   | ||||
| @@ -62,7 +62,7 @@ public class SysLog implements Serializable { | ||||
|     /** | ||||
|      * 请求头 | ||||
|      */ | ||||
|     private String requestHeader; | ||||
|     private String requestHeaders; | ||||
|  | ||||
|     /** | ||||
|      * 请求体 | ||||
| @@ -77,7 +77,7 @@ public class SysLog implements Serializable { | ||||
|     /** | ||||
|      * 响应头 | ||||
|      */ | ||||
|     private String responseHeader; | ||||
|     private String responseHeaders; | ||||
|  | ||||
|     /** | ||||
|      * 响应体 | ||||
|   | ||||
| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.monitor.model.query; | ||||
|  | ||||
| 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; | ||||
|  | ||||
| /** | ||||
|  * 系统日志查询条件 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/17 23:31 | ||||
|  */ | ||||
| @Data | ||||
| @ParameterObject | ||||
| @Schema(description = "系统日志查询条件") | ||||
| public class SystemLogQuery implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @Schema(description = "创建时间") | ||||
|     @Query(type = Query.Type.BETWEEN) | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private List<Date> createTime; | ||||
| } | ||||
| @@ -0,0 +1,121 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.monitor.model.vo; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| /** | ||||
|  * 系统日志详情信息 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/18 20:19 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "系统日志详情信息") | ||||
| public class SystemLogDetailVO extends LogVO implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 日志ID | ||||
|      */ | ||||
|     @Schema(description = "日志ID") | ||||
|     private Long logId; | ||||
|  | ||||
|     /** | ||||
|      * 日志描述 | ||||
|      */ | ||||
|     @Schema(description = "日志描述") | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 请求URL | ||||
|      */ | ||||
|     @Schema(description = "请求URL") | ||||
|     private String requestUrl; | ||||
|  | ||||
|     /** | ||||
|      * 请求方式 | ||||
|      */ | ||||
|     @Schema(description = "请求方式") | ||||
|     private String requestMethod; | ||||
|  | ||||
|     /** | ||||
|      * 请求头 | ||||
|      */ | ||||
|     @Schema(description = "请求头") | ||||
|     private String requestHeaders; | ||||
|  | ||||
|     /** | ||||
|      * 请求体 | ||||
|      */ | ||||
|     @Schema(description = "请求体") | ||||
|     private String requestBody; | ||||
|  | ||||
|     /** | ||||
|      * 状态码 | ||||
|      */ | ||||
|     @Schema(description = "状态码") | ||||
|     private Integer statusCode; | ||||
|  | ||||
|     /** | ||||
|      * 响应头 | ||||
|      */ | ||||
|     @Schema(description = "响应头") | ||||
|     private String responseHeaders; | ||||
|  | ||||
|     /** | ||||
|      * 响应体 | ||||
|      */ | ||||
|     @Schema(description = "响应体") | ||||
|     private String responseBody; | ||||
|  | ||||
|     /** | ||||
|      * 请求耗时(ms) | ||||
|      */ | ||||
|     @Schema(description = "请求耗时(ms)") | ||||
|     private Long elapsedTime; | ||||
|  | ||||
|     /** | ||||
|      * 客户端IP | ||||
|      */ | ||||
|     @Schema(description = "客户端IP") | ||||
|     private String clientIp; | ||||
|  | ||||
|     /** | ||||
|      * IP归属地 | ||||
|      */ | ||||
|     @Schema(description = "IP归属地") | ||||
|     private String location; | ||||
|  | ||||
|     /** | ||||
|      * 浏览器 | ||||
|      */ | ||||
|     @Schema(description = "浏览器") | ||||
|     private String browser; | ||||
|  | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @Schema(description = "创建时间") | ||||
|     private LocalDateTime createTime; | ||||
| } | ||||
| @@ -0,0 +1,109 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.monitor.model.vo; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| /** | ||||
|  * 系统日志信息 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/17 23:29 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "系统日志信息") | ||||
| public class SystemLogVO extends LogVO implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 日志ID | ||||
|      */ | ||||
|     @Schema(description = "日志ID") | ||||
|     private Long logId; | ||||
|  | ||||
|     /** | ||||
|      * 日志描述 | ||||
|      */ | ||||
|     @Schema(description = "日志描述") | ||||
|     private String description; | ||||
|  | ||||
|     /** | ||||
|      * 状态码 | ||||
|      */ | ||||
|     @Schema(description = "状态码") | ||||
|     private Integer statusCode; | ||||
|  | ||||
|     /** | ||||
|      * 请求方式 | ||||
|      */ | ||||
|     @Schema(description = "请求方式") | ||||
|     private String requestMethod; | ||||
|  | ||||
|     /** | ||||
|      * 请求URL | ||||
|      */ | ||||
|     @Schema(description = "请求URL") | ||||
|     private String requestUrl; | ||||
|  | ||||
|     /** | ||||
|      * 请求耗时(ms) | ||||
|      */ | ||||
|     @Schema(description = "请求耗时(ms)") | ||||
|     private Long elapsedTime; | ||||
|  | ||||
|     /** | ||||
|      * 客户端IP | ||||
|      */ | ||||
|     @Schema(description = "客户端IP") | ||||
|     private String clientIp; | ||||
|  | ||||
|     /** | ||||
|      * IP归属地 | ||||
|      */ | ||||
|     @Schema(description = "IP归属地") | ||||
|     private String location; | ||||
|  | ||||
|     /** | ||||
|      * 浏览器 | ||||
|      */ | ||||
|     @Schema(description = "浏览器") | ||||
|     private String browser; | ||||
|  | ||||
|     /** | ||||
|      * 错误信息 | ||||
|      */ | ||||
|     @Schema(description = "错误信息") | ||||
|     private String errorMsg; | ||||
|  | ||||
|     /** | ||||
|      * 异常详情 | ||||
|      */ | ||||
|     @Schema(description = "异常详情") | ||||
|     private String exceptionDetail; | ||||
|  | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @Schema(description = "创建时间") | ||||
|     private LocalDateTime createTime; | ||||
| } | ||||
| @@ -20,8 +20,11 @@ import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||
| import top.charles7c.cnadmin.common.model.vo.PageInfo; | ||||
| import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.query.OperationLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.query.SystemLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.LoginLogVO; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.OperationLogVO; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.SystemLogDetailVO; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.SystemLogVO; | ||||
|  | ||||
| /** | ||||
|  * 系统日志业务接口 | ||||
| @@ -52,4 +55,24 @@ public interface LogService { | ||||
|      * @return 登录日志分页信息 | ||||
|      */ | ||||
|     PageInfo<LoginLogVO> list(LoginLogQuery query, PageQuery pageQuery); | ||||
|  | ||||
|     /** | ||||
|      * 分页查询系统日志列表 | ||||
|      * | ||||
|      * @param query | ||||
|      *            查询条件 | ||||
|      * @param pageQuery | ||||
|      *            分页查询条件 | ||||
|      * @return 系统日志分页信息 | ||||
|      */ | ||||
|     PageInfo<SystemLogVO> list(SystemLogQuery query, PageQuery pageQuery); | ||||
|  | ||||
|     /** | ||||
|      * 查看系统日志详情 | ||||
|      * | ||||
|      * @param logId | ||||
|      *            日志ID | ||||
|      * @return 系统日志详情 | ||||
|      */ | ||||
|     SystemLogDetailVO detail(Long logId); | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,7 @@ import org.springframework.stereotype.Service; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||
| @@ -37,13 +38,13 @@ import top.charles7c.cnadmin.common.model.vo.PageInfo; | ||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||
| import top.charles7c.cnadmin.common.util.ReflectUtils; | ||||
| import top.charles7c.cnadmin.common.util.helper.QueryHelper; | ||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | ||||
| import top.charles7c.cnadmin.monitor.mapper.LogMapper; | ||||
| import top.charles7c.cnadmin.monitor.model.entity.SysLog; | ||||
| import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.query.OperationLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.LogVO; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.LoginLogVO; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.OperationLogVO; | ||||
| import top.charles7c.cnadmin.monitor.model.query.SystemLogQuery; | ||||
| import top.charles7c.cnadmin.monitor.model.vo.*; | ||||
| import top.charles7c.cnadmin.monitor.service.LogService; | ||||
| import top.charles7c.cnadmin.system.service.UserService; | ||||
|  | ||||
| @@ -94,7 +95,8 @@ public class LogServiceImpl implements LogService { | ||||
|     @Override | ||||
|     public PageInfo<LoginLogVO> list(LoginLogQuery query, PageQuery pageQuery) { | ||||
|         QueryWrapper<SysLog> queryWrapper = QueryHelper.build(query); | ||||
|         queryWrapper.and(qw -> qw.like("request_url", "/auth/login").or().like("request_url", "/auth/logout")); | ||||
|         queryWrapper.lambda() | ||||
|             .and(qw -> qw.like(SysLog::getRequestUrl, "/auth/login").or().like(SysLog::getRequestUrl, "/auth/logout")); | ||||
|  | ||||
|         // 限定查询信息 | ||||
|         String[] fieldsName = ReflectUtils.getNonStaticFieldsName(LoginLogVO.class); | ||||
| @@ -111,6 +113,35 @@ public class LogServiceImpl implements LogService { | ||||
|         return pageInfo; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public PageInfo<SystemLogVO> list(SystemLogQuery query, PageQuery pageQuery) { | ||||
|         QueryWrapper<SysLog> queryWrapper = QueryHelper.build(query); | ||||
|  | ||||
|         // 限定查询信息 | ||||
|         String[] fieldsName = ReflectUtils.getNonStaticFieldsName(SystemLogVO.class); | ||||
|         List<String> columns = Arrays.stream(fieldsName).map(StrUtil::toUnderlineCase) | ||||
|             .filter(n -> !n.endsWith("string")).collect(Collectors.toList()); | ||||
|         queryWrapper.select(columns); | ||||
|  | ||||
|         // 分页查询 | ||||
|         IPage<SysLog> page = logMapper.selectPage(pageQuery.toPage(), queryWrapper); | ||||
|         PageInfo<SystemLogVO> pageInfo = PageInfo.build(page, SystemLogVO.class); | ||||
|  | ||||
|         // 填充数据 | ||||
|         pageInfo.getList().forEach(this::fill); | ||||
|         return pageInfo; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SystemLogDetailVO detail(Long logId) { | ||||
|         SysLog sysLog = logMapper.selectById(logId); | ||||
|         ValidationUtils.exIfNull(sysLog, String.format("ID为 [%s] 的日志已不存在", logId)); | ||||
|  | ||||
|         SystemLogDetailVO detailVO = BeanUtil.copyProperties(sysLog, SystemLogDetailVO.class); | ||||
|         this.fill(detailVO); | ||||
|         return detailVO; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 填充数据 | ||||
|      * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user