Commit 30076f6472fc56f2a3ef25eea7f9b4470bc62a55
1 parent
ec8f181f
完成操作日志的存储
Showing
7 changed files
with
83 additions
and
31 deletions
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
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 | +} |