Commit 30076f6472fc56f2a3ef25eea7f9b4470bc62a55

Authored by YunaiV
1 parent ec8f181f

完成操作日志的存储

sql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 Target Server Version : 50718 11 Target Server Version : 50718
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 14/01/2021 21:27:23 14 + Date: 17/01/2021 01:21:15
15 */ 15 */
16 16
17 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
@@ -262,28 +262,36 @@ CREATE TABLE `sys_notice` ( @@ -262,28 +262,36 @@ CREATE TABLE `sys_notice` (
262 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='通知公告表'; 262 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='通知公告表';
263 263
264 -- ---------------------------- 264 -- ----------------------------
265 --- Table structure for sys_oper_log  
266 --- ----------------------------  
267 -DROP TABLE IF EXISTS `sys_oper_log`;  
268 -CREATE TABLE `sys_oper_log` (  
269 - `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',  
270 - `title` varchar(50) DEFAULT '' COMMENT '模块标题',  
271 - `business_type` int(2) DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)',  
272 - `method` varchar(100) DEFAULT '' COMMENT '方法名称',  
273 - `request_method` varchar(10) DEFAULT '' COMMENT '请求方式',  
274 - `operator_type` int(1) DEFAULT '0' COMMENT '操作类别(0其它 1后台用户 2手机端用户)',  
275 - `oper_name` varchar(50) DEFAULT '' COMMENT '操作人员',  
276 - `dept_name` varchar(50) DEFAULT '' COMMENT '部门名称',  
277 - `oper_url` varchar(255) DEFAULT '' COMMENT '请求URL',  
278 - `oper_ip` varchar(50) DEFAULT '' COMMENT '主机地址',  
279 - `oper_location` varchar(255) DEFAULT '' COMMENT '操作地点',  
280 - `oper_param` varchar(2000) DEFAULT '' COMMENT '请求参数',  
281 - `json_result` varchar(2000) DEFAULT '' COMMENT '返回参数',  
282 - `status` int(1) DEFAULT '0' COMMENT '操作状态(0正常 1异常)',  
283 - `error_msg` varchar(2000) DEFAULT '' COMMENT '错误消息',  
284 - `oper_time` datetime DEFAULT NULL COMMENT '操作时间',  
285 - PRIMARY KEY (`oper_id`)  
286 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录'; 265 +-- Table structure for sys_operate_log
  266 +-- ----------------------------
  267 +DROP TABLE IF EXISTS `sys_operate_log`;
  268 +CREATE TABLE `sys_operate_log` (
  269 + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',
  270 + `trace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '链路追踪编号',
  271 + `user_id` bigint(20) NOT NULL COMMENT '用户编号',
  272 + `module` varchar(50) NOT NULL COMMENT '模块标题',
  273 + `name` varchar(50) NOT NULL COMMENT '操作名',
  274 + `operate_type` bigint(4) NOT NULL DEFAULT '0' COMMENT '操作分类',
  275 + `content` varchar(2000) NOT NULL DEFAULT '' COMMENT '操作内容',
  276 + `exts` varchar(512) NOT NULL DEFAULT '' COMMENT '拓展字段',
  277 + `request_method` varchar(16) DEFAULT '' COMMENT '请求方法名',
  278 + `request_url` varchar(255) DEFAULT '' COMMENT '请求地址',
  279 + `user_ip` varchar(50) DEFAULT NULL COMMENT '用户 IP',
  280 + `user_agent` varchar(50) DEFAULT NULL COMMENT '浏览器 UA',
  281 + `java_method` varchar(512) NOT NULL DEFAULT '' COMMENT 'Java 方法名',
  282 + `java_method_args` varchar(8000) DEFAULT '' COMMENT 'Java 方法的参数',
  283 + `start_time` datetime NOT NULL COMMENT '操作时间',
  284 + `duration` int(11) NOT NULL COMMENT '执行时长',
  285 + `result_code` int(11) NOT NULL DEFAULT '0' COMMENT '结果码',
  286 + `result_msg` varchar(512) DEFAULT '' COMMENT '结果提示',
  287 + `result_data` varchar(4000) DEFAULT '' COMMENT '结果数据',
  288 + `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  289 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  290 + `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  291 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  292 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  293 + PRIMARY KEY (`id`) USING BTREE
  294 +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
287 295
288 -- ---------------------------- 296 -- ----------------------------
289 -- Table structure for sys_post 297 -- Table structure for sys_post
@@ -367,7 +375,7 @@ CREATE TABLE `sys_user` ( @@ -367,7 +375,7 @@ CREATE TABLE `sys_user` (
367 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 375 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
368 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 376 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
369 PRIMARY KEY (`id`) USING BTREE 377 PRIMARY KEY (`id`) USING BTREE
370 -) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表'; 378 +) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
371 379
372 -- ---------------------------- 380 -- ----------------------------
373 -- Table structure for sys_user_role 381 -- Table structure for sys_user_role
src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
@@ -272,7 +272,7 @@ public class OperateLogAspect { @@ -272,7 +272,7 @@ public class OperateLogAspect {
272 return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass); 272 return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass);
273 } 273 }
274 274
275 - private static Map<String, Object> obtainMethodArgs(ProceedingJoinPoint joinPoint) { 275 + private static String obtainMethodArgs(ProceedingJoinPoint joinPoint) {
276 // TODO 提升:参数脱敏和忽略 276 // TODO 提升:参数脱敏和忽略
277 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); 277 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
278 String[] argNames = methodSignature.getParameterNames(); 278 String[] argNames = methodSignature.getParameterNames();
@@ -285,7 +285,7 @@ public class OperateLogAspect { @@ -285,7 +285,7 @@ public class OperateLogAspect {
285 // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起 285 // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
286 args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]"); 286 args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
287 } 287 }
288 - return args; 288 + return JSON.toJSONString(argValues);
289 } 289 }
290 290
291 private static String obtainResultData(Object result) { 291 private static String obtainResultData(Object result) {
src/main/java/cn/iocoder/dashboard/framework/package-info.java 0 → 100644
  1 +/**
  2 + * 该包是技术组件,每个子包,代表一个组件。每个组件包括两部分:
  3 + * 1. core 包:是该组件的核心分装
  4 + * 2. config 包:是该组件基于 Spring 的配置
  5 + *
  6 + * 技术组件,也分成两类:
  7 + * 1. 框架组件:和我们熟悉的 MyBatis、Redis 等等的拓展
  8 + * 2. 业务组件:和业务相关的组件的封装,例如说数据字典、操作日志等等。
  9 + */
  10 +package cn.iocoder.dashboard.framework;
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java
@@ -6,7 +6,6 @@ import lombok.Data; @@ -6,7 +6,6 @@ import lombok.Data;
6 import javax.validation.constraints.NotEmpty; 6 import javax.validation.constraints.NotEmpty;
7 import javax.validation.constraints.NotNull; 7 import javax.validation.constraints.NotNull;
8 import java.util.Date; 8 import java.util.Date;
9 -import java.util.Map;  
10 9
11 /** 10 /**
12 * 操作日志 Base VO,提供给添加、修改、详细的子 VO 使用 11 * 操作日志 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -56,7 +55,7 @@ public class SysOperateLogBaseVO { @@ -56,7 +55,7 @@ public class SysOperateLogBaseVO {
56 private String javaMethod; 55 private String javaMethod;
57 56
58 @ApiModelProperty(value = "Java 方法的参数") 57 @ApiModelProperty(value = "Java 方法的参数")
59 - private Map<String, Object> javaMethodArgs; 58 + private String javaMethodArgs;
60 59
61 @ApiModelProperty(value = "开始时间", required = true) 60 @ApiModelProperty(value = "开始时间", required = true)
62 @NotNull(message = "开始时间不能为空") 61 @NotNull(message = "开始时间不能为空")
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
@@ -25,6 +25,16 @@ import java.util.Map; @@ -25,6 +25,16 @@ import java.util.Map;
25 public class SysOperateLogDO extends BaseDO { 25 public class SysOperateLogDO extends BaseDO {
26 26
27 /** 27 /**
  28 + * {@link #javaMethodArgs} 的最大长度
  29 + */
  30 + public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000;
  31 +
  32 + /**
  33 + * {@link #resultData} 的最大长度
  34 + */
  35 + public static final Integer RESULT_MAX_LENGTH = 4000;
  36 +
  37 + /**
28 * 日志主键 38 * 日志主键
29 */ 39 */
30 @TableId 40 @TableId
@@ -54,6 +64,7 @@ public class SysOperateLogDO extends BaseDO { @@ -54,6 +64,7 @@ public class SysOperateLogDO extends BaseDO {
54 * 64 *
55 * 枚举 {@link SysOperateLogTypeEnum} 65 * 枚举 {@link SysOperateLogTypeEnum}
56 */ 66 */
  67 + @TableField("operate_type")
57 private Integer type; 68 private Integer type;
58 /** 69 /**
59 * 操作内容,记录整个操作的明细 70 * 操作内容,记录整个操作的明细
@@ -94,9 +105,12 @@ public class SysOperateLogDO extends BaseDO { @@ -94,9 +105,12 @@ public class SysOperateLogDO extends BaseDO {
94 private String javaMethod; 105 private String javaMethod;
95 /** 106 /**
96 * Java 方法的参数 107 * Java 方法的参数
  108 + *
  109 + * 实际格式为 Map<String, Object>
  110 + * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败
  111 + * 其中,key 为参数名,value 为参数值
97 */ 112 */
98 - @TableField(typeHandler = FastjsonTypeHandler.class)  
99 - private Map<String, Object> javaMethodArgs; 113 + private String javaMethodArgs;
100 /** 114 /**
101 * 开始时间 115 * 开始时间
102 */ 116 */
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
@@ -5,12 +5,15 @@ import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert; @@ -5,12 +5,15 @@ import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert;
5 import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper; 5 import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper;
6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; 6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
7 import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService; 7 import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService;
  8 +import cn.iocoder.dashboard.util.string.StrUtils;
8 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.scheduling.annotation.Async; 10 import org.springframework.scheduling.annotation.Async;
10 import org.springframework.stereotype.Service; 11 import org.springframework.stereotype.Service;
11 12
12 import javax.annotation.Resource; 13 import javax.annotation.Resource;
13 14
  15 +import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.*;
  16 +
14 @Service 17 @Service
15 @Slf4j 18 @Slf4j
16 public class SysOperateLogServiceImpl implements SysOperateLogService { 19 public class SysOperateLogServiceImpl implements SysOperateLogService {
@@ -21,8 +24,10 @@ public class SysOperateLogServiceImpl implements SysOperateLogService { @@ -21,8 +24,10 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
21 @Override 24 @Override
22 @Async 25 @Async
23 public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) { 26 public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) {
24 - SysOperateLogDO logDO = SysOperateLogConvert.INSTANCE.convert(reqVO);  
25 try { 27 try {
  28 + SysOperateLogDO logDO = SysOperateLogConvert.INSTANCE.convert(reqVO);
  29 + logDO.setJavaMethodArgs(StrUtils.maxLength(logDO.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
  30 + logDO.setResultData(StrUtils.maxLength(logDO.getResultData(), RESULT_MAX_LENGTH));
26 operateLogMapper.insert(logDO); 31 operateLogMapper.insert(logDO);
27 } catch (Throwable throwable) { 32 } catch (Throwable throwable) {
28 // 仅仅打印日志,不对外抛出。原因是,还是要保留现场数据。 33 // 仅仅打印日志,不对外抛出。原因是,还是要保留现场数据。
src/main/java/cn/iocoder/dashboard/util/string/StrUtils.java 0 → 100644
  1 +package cn.iocoder.dashboard.util.string;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +
  5 +/**
  6 + * 字符串工具类
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public class StrUtils {
  11 +
  12 + public static String maxLength(CharSequence str, int maxLength) {
  13 + return StrUtil.maxLength(str, maxLength - 3); // -3 的原因,是该方法会补充 ... 恰好
  14 + }
  15 +
  16 +}