快驴生鲜系统用户操作日志开发详解:从需求到部署优化全流程
分类:IT频道
时间:2026-02-08 23:40
浏览:24
概述
一、需求分析 1.日志记录目的: -审计追踪:记录用户所有关键操作,便于问题排查和合规性检查 -安全监控:识别异常操作行为,预防潜在安全威胁 -数据分析:了解用户行为模式,优化系统功能 2.需记录的操作类型: -登录/登出操作 -权限变更操作 -关键数据修改(商品信息
内容
一、需求分析
1. 日志记录目的:
- 审计追踪:记录用户所有关键操作,便于问题排查和合规性检查
- 安全监控:识别异常操作行为,预防潜在安全威胁
- 数据分析:了解用户行为模式,优化系统功能
2. 需记录的操作类型:
- 登录/登出操作
- 权限变更操作
- 关键数据修改(商品信息、订单状态、价格调整等)
- 批量操作(导入/导出、批量删除等)
- 系统配置变更
3. 日志内容要求:
- 操作时间
- 操作用户
- 操作类型
- 操作对象(如商品ID、订单号等)
- 操作前数据状态(可选)
- 操作后数据状态
- 操作结果(成功/失败)
- 客户端IP地址
二、技术方案设计
1. 日志存储方案
方案一:数据库存储
- 优点:便于查询、结构化存储
- 缺点:高并发写入可能影响性能
- 实现:创建`user_operation_log`表
```sql
CREATE TABLE user_operation_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL COMMENT 用户ID,
username VARCHAR(50) NOT NULL COMMENT 用户名,
operation_type VARCHAR(50) NOT NULL COMMENT 操作类型,
operation_object VARCHAR(100) COMMENT 操作对象ID,
old_value TEXT COMMENT 操作前值,
new_value TEXT COMMENT 操作后值,
result VARCHAR(20) NOT NULL COMMENT 操作结果(SUCCESS/FAIL),
ip_address VARCHAR(50) COMMENT 客户端IP,
user_agent VARCHAR(255) COMMENT 用户代理,
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 操作时间,
INDEX idx_user_id (user_id),
INDEX idx_operation_time (create_time),
INDEX idx_operation_type (operation_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=用户操作日志表;
```
方案二:文件存储+ELK
- 优点:高性能写入,适合大规模日志
- 缺点:需要额外维护ELK栈
- 实现:使用Logback/Log4j2写入文件,通过Filebeat收集到Elasticsearch
2. 日志记录方式
方案一:AOP切面实现
```java
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private UserOperationLogService logService;
@Pointcut("@annotation(com.kuailu.annotation.OperationLog)")
public void logPointCut() {}
@AfterReturning(pointcut = "logPointCut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
// 获取方法注解信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperationLog operationLog = method.getAnnotation(OperationLog.class);
// 获取请求参数
Object[] args = joinPoint.getArgs();
// 构建日志对象
UserOperationLog log = new UserOperationLog();
// 设置日志属性...
logService.save(log);
}
}
```
方案二:手动调用服务层
在每个需要记录日志的方法中显式调用日志服务
3. 自定义注解设计
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
/
* 操作类型
*/
String operationType();
/
* 操作对象类型
*/
String objectType() default "";
/
* 是否记录请求参数
*/
boolean logParams() default true;
/
* 是否记录响应结果
*/
boolean logResult() default false;
/
* 操作描述
*/
String description() default "";
}
```
三、具体实现
1. 日志服务实现
```java
@Service
public class UserOperationLogServiceImpl implements UserOperationLogService {
@Autowired
private UserOperationLogMapper logMapper;
@Autowired
private HttpServletRequest request;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void save(UserOperationLogDTO logDTO) {
// 获取当前用户信息
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// 构建日志实体
UserOperationLog log = new UserOperationLog();
log.setUserId(userDetails.getUserId());
log.setUsername(userDetails.getUsername());
log.setOperationType(logDTO.getOperationType());
log.setOperationObject(logDTO.getOperationObject());
log.setOldValue(logDTO.getOldValue());
log.setNewValue(logDTO.getNewValue());
log.setResult(logDTO.getResult());
log.setIpAddress(getIpAddress());
log.setUserAgent(request.getHeader("User-Agent"));
// 保存日志
logMapper.insert(log);
}
private String getIpAddress() {
// IP获取逻辑...
}
}
```
2. 控制器示例
```java
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@OperationLog(
operationType = "UPDATE_PRODUCT",
objectType = "PRODUCT",
description = "更新商品信息"
)
@PutMapping("/{id}")
public Result updateProduct(@PathVariable Long id, @RequestBody ProductDTO productDTO) {
// 获取修改前数据
Product oldProduct = productService.getById(id);
// 执行更新
productService.update(id, productDTO);
// 获取修改后数据
Product newProduct = productService.getById(id);
// 构建日志参数(实际可通过AOP自动获取)
Map logParams = new HashMap<>();
logParams.put("oldProduct", oldProduct);
logParams.put("newProduct", newProduct);
return Result.success();
}
}
```
四、高级功能实现
1. 异步日志记录
```java
@Configuration
public class AsyncLogConfig {
@Bean("logExecutor")
public Executor logExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("log-executor-");
executor.initialize();
return executor;
}
}
// 在日志服务中添加@Async注解
@Service
public class UserOperationLogServiceImpl implements UserOperationLogService {
@Async("logExecutor")
@Override
public void save(UserOperationLogDTO logDTO) {
// 日志保存逻辑
}
}
```
2. 日志脱敏处理
```java
public class LogDesensitizer {
public static String desensitize(String content, String fieldType) {
if (StringUtils.isEmpty(content)) {
return content;
}
switch (fieldType) {
case "phone":
return content.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1$2");
case "id_card":
return content.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1$2");
case "address":
return content.length() > 6 ? content.substring(0, 3) + "*" + content.substring(content.length()-3) : content;
default:
return content;
}
}
}
```
3. 日志查询接口
```java
@RestController
@RequestMapping("/api/logs")
public class LogController {
@Autowired
private UserOperationLogService logService;
@GetMapping
public Result queryLogs(
@RequestParam(required = false) String username,
@RequestParam(required = false) String operationType,
@RequestParam(required = false) Date startTime,
@RequestParam(required = false) Date endTime,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
PageInfo pageInfo = logService.queryLogs(
username, operationType, startTime, endTime, pageNum, pageSize);
return Result.success(pageInfo);
}
}
```
五、部署与监控
1. 日志清理策略:
- 设置定时任务定期清理过期日志(如保留90天)
- 考虑将历史日志归档到廉价存储
2. 监控告警:
- 监控日志写入失败情况
- 对异常操作频率设置告警阈值
3. 性能优化:
- 批量插入日志
- 对高频操作考虑采样记录
六、测试用例
1. 正常操作日志记录:
- 测试各种操作类型是否能正确记录
- 验证日志内容完整性
2. 异常情况处理:
- 测试日志服务不可用时系统行为
- 测试高并发场景下的日志记录
3. 脱敏测试:
- 验证敏感信息是否被正确脱敏
4. 查询功能测试:
- 测试各种查询条件的组合效果
- 验证分页功能
七、后续优化方向
1. 引入日志分析平台(如ELK)实现可视化分析
2. 添加操作日志导出功能
3. 实现操作日志的自动关联(如根据订单号关联所有相关操作)
4. 添加操作日志的审计签名功能
以上是快驴生鲜系统用户操作日志开发的基本记录,实际实现时可根据具体业务需求和技术栈进行调整。
评论