一、需求分析 1.日志记录目的: -审计跟踪:记录用户所有关键操作,便于问题排查和合规性检查 -安全监控:检测异常行为,预防潜在安全威胁 -数据分析:了解用户行为模式,优化系统功能 2.需要记录的操作类型: -登录/登出操作 -权限变更操作 -关键业务操作(如订单创建
一、需求分析
1. 日志记录目的:
- 审计跟踪:记录用户所有关键操作,便于问题排查和合规性检查
- 安全监控:检测异常行为,预防潜在安全威胁
- 数据分析:了解用户行为模式,优化系统功能
2. 需要记录的操作类型:
- 登录/登出操作
- 权限变更操作
- 关键业务操作(如订单创建、修改、删除)
- 数据导入导出操作
- 系统配置变更
3. 日志内容要求:
- 操作时间
- 操作用户
- 操作类型
- 操作对象(如订单ID、商品ID等)
- 操作结果(成功/失败)
- 操作详情(如修改前后的值)
- 客户端信息(IP地址、设备类型等)
二、技术方案设计
1. 日志存储方案
方案一:数据库存储
- 优点:结构化查询方便,易于集成现有系统
- 缺点:高并发写入可能影响性能,需要定期归档
方案二:文件存储+ELK
- 优点:高性能写入,适合大规模日志处理
- 缺点:需要额外维护ELK栈,查询复杂度较高
最终选择:采用数据库存储为主,文件存储为辅的混合方案
- 核心业务日志存入MySQL
- 非关键日志存入文件系统,定期归档
2. 日志表设计
```sql
CREATE TABLE `operation_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID,
`user_id` bigint(20) NOT NULL COMMENT 操作用户ID,
`username` varchar(50) NOT NULL COMMENT 用户名,
`operation_type` varchar(50) NOT NULL COMMENT 操作类型,
`operation_module` varchar(50) NOT NULL COMMENT 操作模块,
`operation_target` varchar(255) DEFAULT NULL COMMENT 操作对象ID,
`operation_content` text COMMENT 操作内容详情,
`operation_result` varchar(20) NOT NULL COMMENT 操作结果(SUCCESS/FAIL),
`client_ip` varchar(50) DEFAULT NULL COMMENT 客户端IP,
`user_agent` varchar(500) DEFAULT NULL COMMENT 用户代理信息,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,
`extend_info` json DEFAULT NULL COMMENT 扩展信息,
PRIMARY KEY (`id`),
KEY `idx_user_time` (`user_id`,`create_time`),
KEY `idx_operation_time` (`operation_type`,`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=用户操作日志表;
```
3. 实现方式
方案一:AOP切面实现
```java
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private OperationLogService logService;
@Pointcut("@annotation(com.kuailu.annotation.OperationLog)")
public void logPointCut() {}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
// 获取方法签名
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
// 获取注解信息
OperationLog operationLog = method.getAnnotation(OperationLog.class);
if (operationLog == null) {
return point.proceed();
}
// 执行方法
Object result = point.proceed();
// 记录日志
try {
saveLog(point, operationLog, System.currentTimeMillis() - beginTime, result);
} catch (Exception e) {
log.error("记录操作日志异常: {}", e.getMessage());
}
return result;
}
private void saveLog(ProceedingJoinPoint point, OperationLog operationLog,
long costTime, Object result) {
// 获取请求信息
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
// 构建日志对象
OperationLogDTO logDTO = new OperationLogDTO();
logDTO.setOperationType(operationLog.value().name());
logDTO.setOperationModule(operationLog.module());
// ...其他字段设置
logService.save(logDTO);
}
}
```
方案二:手动调用记录
```java
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OperationLogService logService;
@Override
public Result createOrder(OrderCreateDTO dto) {
try {
// 业务逻辑...
// 记录成功日志
OperationLogDTO logDTO = OperationLogDTO.builder()
.userId(getCurrentUserId())
.username(getCurrentUsername())
.operationType(OperationType.CREATE)
.operationModule("ORDER")
.operationTarget(orderId.toString())
.operationContent("创建订单: " + JsonUtils.toJson(dto))
.operationResult("SUCCESS")
.clientIp(getRemoteIp())
.build();
logService.save(logDTO);
return Result.success();
} catch (Exception e) {
// 记录失败日志
logService.saveFailedLog(...);
throw e;
}
}
}
```
最终选择:采用AOP+注解方式为主,关键操作手动记录为辅的混合方案
4. 自定义注解设计
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
/
* 操作类型
*/
OperationType value();
/
* 操作模块
*/
String module() default "";
/
* 是否记录请求参数
*/
boolean logParams() default true;
/
* 是否记录响应结果
*/
boolean logResult() default false;
/
* 成功时记录的额外信息
*/
String successMsg() default "";
/
* 失败时记录的额外信息
*/
String failMsg() default "";
}
public enum OperationType {
CREATE("创建"),
UPDATE("修改"),
DELETE("删除"),
QUERY("查询"),
EXPORT("导出"),
IMPORT("导入"),
LOGIN("登录"),
LOGOUT("登出"),
// 其他操作类型...
;
// 省略构造方法等...
}
```
三、实现细节
1. 日志内容脱敏处理:
- 对敏感信息如密码、手机号等进行脱敏处理
- 实现`SensitiveDataProcessor`接口进行自定义脱敏
2. 异步记录日志:
- 使用Spring的`@Async`注解实现异步记录
- 配置线程池参数
```java
@Service
public class AsyncOperationLogServiceImpl implements OperationLogService {
@Async("logTaskExecutor")
@Override
public void save(OperationLogDTO logDTO) {
// 实际保存逻辑
}
}
@Configuration
public class AsyncConfig {
@Bean("logTaskExecutor")
public Executor logTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("log-executor-");
executor.initialize();
return executor;
}
}
```
3. 日志查询接口:
- 提供按用户、时间范围、操作类型等条件的查询
- 实现分页查询
```java
@RestController
@RequestMapping("/api/operation-logs")
public class OperationLogController {
@Autowired
private OperationLogService logService;
@GetMapping
public Result
> queryLogs(
@RequestParam(required = false) Long userId,
@RequestParam(required = false) String operationType,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "20") Integer pageSize) {
PageData pageData = logService.queryLogs(
userId, operationType, startTime, endTime, pageNum, pageSize);
return Result.success(pageData);
}
}
```
四、性能优化
1. 批量插入优化:
- 实现日志批量插入功能,减少数据库IO
- 设置合理的批量大小(如100条/批)
2. 日志分级存储:
- 热点数据(最近7天)存MySQL
- 历史数据归档到文件系统或对象存储
3. 索引优化:
- 为常用查询字段创建索引
- 避免过度索引影响写入性能
五、安全考虑
1. 日志访问权限控制:
- 只有管理员角色可以查看操作日志
- 实现细粒度的权限控制(如只能查看自己部门的日志)
2. 日志防篡改:
- 考虑对关键日志实现数字签名
- 定期校验日志完整性
3. 日志保留策略:
- 根据业务需求和合规要求设置合理的日志保留期限
- 实现自动清理过期日志的功能
六、部署与监控
1. 日志收集与监控:
- 集成ELK或Prometheus+Grafana实现日志可视化
- 设置异常操作告警规则
2. 日志备份策略:
- 定期备份数据库日志表
- 重要日志实现异地备份
七、测试要点
1. 功能测试:
- 验证各种操作类型是否正确记录
- 验证敏感信息是否脱敏
- 验证异常情况下日志是否记录完整
2. 性能测试:
- 高并发场景下日志记录性能
- 批量插入性能
- 日志查询响应时间
3. 安全测试:
- 验证日志访问权限控制
- 验证日志防篡改机制
八、后续优化方向
1. 实现日志行为分析功能,自动检测异常操作模式
2. 增加日志压缩功能,减少存储空间占用
3. 实现日志跨系统关联分析(如与登录日志关联)
4. 增加操作回滚功能,基于操作日志实现部分场景的回滚
通过以上设计和实现,快驴生鲜系统的用户操作日志功能能够满足审计、安全和业务分析的需求,同时保证了系统的高性能和稳定性。