完成操作日志的存储

This commit is contained in:
YunaiV 2021-01-17 01:21:54 +08:00
parent ec8f181f2f
commit 30076f6472
7 changed files with 82 additions and 30 deletions

View File

@ -11,7 +11,7 @@
Target Server Version : 50718
File Encoding : 65001
Date: 14/01/2021 21:27:23
Date: 17/01/2021 01:21:15
*/
SET NAMES utf8mb4;
@ -262,28 +262,36 @@ CREATE TABLE `sys_notice` (
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='通知公告表';
-- ----------------------------
-- Table structure for sys_oper_log
-- Table structure for sys_operate_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_oper_log`;
CREATE TABLE `sys_oper_log` (
`oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',
`title` varchar(50) DEFAULT '' COMMENT '模块标题',
`business_type` int(2) DEFAULT '0' COMMENT '业务类型0其它 1新增 2修改 3删除',
`method` varchar(100) DEFAULT '' COMMENT '方法名称',
`request_method` varchar(10) DEFAULT '' COMMENT '请求方式',
`operator_type` int(1) DEFAULT '0' COMMENT '操作类别0其它 1后台用户 2手机端用户',
`oper_name` varchar(50) DEFAULT '' COMMENT '操作人员',
`dept_name` varchar(50) DEFAULT '' COMMENT '部门名称',
`oper_url` varchar(255) DEFAULT '' COMMENT '请求URL',
`oper_ip` varchar(50) DEFAULT '' COMMENT '主机地址',
`oper_location` varchar(255) DEFAULT '' COMMENT '操作地点',
`oper_param` varchar(2000) DEFAULT '' COMMENT '请求参数',
`json_result` varchar(2000) DEFAULT '' COMMENT '返回参数',
`status` int(1) DEFAULT '0' COMMENT '操作状态0正常 1异常',
`error_msg` varchar(2000) DEFAULT '' COMMENT '错误消息',
`oper_time` datetime DEFAULT NULL COMMENT '操作时间',
PRIMARY KEY (`oper_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
DROP TABLE IF EXISTS `sys_operate_log`;
CREATE TABLE `sys_operate_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',
`trace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '链路追踪编号',
`user_id` bigint(20) NOT NULL COMMENT '用户编号',
`module` varchar(50) NOT NULL COMMENT '模块标题',
`name` varchar(50) NOT NULL COMMENT '操作名',
`operate_type` bigint(4) NOT NULL DEFAULT '0' COMMENT '操作分类',
`content` varchar(2000) NOT NULL DEFAULT '' COMMENT '操作内容',
`exts` varchar(512) NOT NULL DEFAULT '' COMMENT '拓展字段',
`request_method` varchar(16) DEFAULT '' COMMENT '请求方法名',
`request_url` varchar(255) DEFAULT '' COMMENT '请求地址',
`user_ip` varchar(50) DEFAULT NULL COMMENT '用户 IP',
`user_agent` varchar(50) DEFAULT NULL COMMENT '浏览器 UA',
`java_method` varchar(512) NOT NULL DEFAULT '' COMMENT 'Java 方法名',
`java_method_args` varchar(8000) DEFAULT '' COMMENT 'Java 方法的参数',
`start_time` datetime NOT NULL COMMENT '操作时间',
`duration` int(11) NOT NULL COMMENT '执行时长',
`result_code` int(11) NOT NULL DEFAULT '0' COMMENT '结果码',
`result_msg` varchar(512) DEFAULT '' COMMENT '结果提示',
`result_data` varchar(4000) DEFAULT '' COMMENT '结果数据',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
-- ----------------------------
-- Table structure for sys_post
@ -367,7 +375,7 @@ CREATE TABLE `sys_user` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
-- ----------------------------
-- Table structure for sys_user_role

View File

@ -272,7 +272,7 @@ public class OperateLogAspect {
return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass);
}
private static Map<String, Object> obtainMethodArgs(ProceedingJoinPoint joinPoint) {
private static String obtainMethodArgs(ProceedingJoinPoint joinPoint) {
// TODO 提升参数脱敏和忽略
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] argNames = methodSignature.getParameterNames();
@ -285,7 +285,7 @@ public class OperateLogAspect {
// 被忽略时标记为 ignore 字符串避免和 null 混在一起
args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
}
return args;
return JSON.toJSONString(argValues);
}
private static String obtainResultData(Object result) {

View File

@ -0,0 +1,10 @@
/**
* 该包是技术组件每个子包代表一个组件每个组件包括两部分
* 1. core 是该组件的核心分装
* 2. config 是该组件基于 Spring 的配置
*
* 技术组件也分成两类
* 1. 框架组件和我们熟悉的 MyBatisRedis 等等的拓展
* 2. 业务组件和业务相关的组件的封装例如说数据字典操作日志等等
*/
package cn.iocoder.dashboard.framework;

View File

@ -6,7 +6,6 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Map;
/**
* 操作日志 Base VO提供给添加修改详细的子 VO 使用
@ -56,7 +55,7 @@ public class SysOperateLogBaseVO {
private String javaMethod;
@ApiModelProperty(value = "Java 方法的参数")
private Map<String, Object> javaMethodArgs;
private String javaMethodArgs;
@ApiModelProperty(value = "开始时间", required = true)
@NotNull(message = "开始时间不能为空")

View File

@ -24,6 +24,16 @@ import java.util.Map;
@EqualsAndHashCode(callSuper = true)
public class SysOperateLogDO extends BaseDO {
/**
* {@link #javaMethodArgs} 的最大长度
*/
public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000;
/**
* {@link #resultData} 的最大长度
*/
public static final Integer RESULT_MAX_LENGTH = 4000;
/**
* 日志主键
*/
@ -54,6 +64,7 @@ public class SysOperateLogDO extends BaseDO {
*
* 枚举 {@link SysOperateLogTypeEnum}
*/
@TableField("operate_type")
private Integer type;
/**
* 操作内容记录整个操作的明细
@ -94,9 +105,12 @@ public class SysOperateLogDO extends BaseDO {
private String javaMethod;
/**
* Java 方法的参数
*
* 实际格式为 Map<String, Object>
* 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是数据库存储有长度限制会进行裁剪会导致 JSON 反序列化失败
* 其中key 为参数名value 为参数值
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private Map<String, Object> javaMethodArgs;
private String javaMethodArgs;
/**
* 开始时间
*/

View File

@ -5,12 +5,15 @@ import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert;
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService;
import cn.iocoder.dashboard.util.string.StrUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.*;
@Service
@Slf4j
public class SysOperateLogServiceImpl implements SysOperateLogService {
@ -21,8 +24,10 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
@Override
@Async
public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) {
SysOperateLogDO logDO = SysOperateLogConvert.INSTANCE.convert(reqVO);
try {
SysOperateLogDO logDO = SysOperateLogConvert.INSTANCE.convert(reqVO);
logDO.setJavaMethodArgs(StrUtils.maxLength(logDO.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
logDO.setResultData(StrUtils.maxLength(logDO.getResultData(), RESULT_MAX_LENGTH));
operateLogMapper.insert(logDO);
} catch (Throwable throwable) {
// 仅仅打印日志不对外抛出原因是还是要保留现场数据

View File

@ -0,0 +1,16 @@
package cn.iocoder.dashboard.util.string;
import cn.hutool.core.util.StrUtil;
/**
* 字符串工具类
*
* @author 芋道源码
*/
public class StrUtils {
public static String maxLength(CharSequence str, int maxLength) {
return StrUtil.maxLength(str, maxLength - 3); // -3 的原因是该方法会补充 ... 恰好
}
}