一、需求分析
1. 日志记录目标:
- 记录用户关键操作行为(登录、下单、修改订单、支付等)
- 追踪系统使用情况,便于问题排查和审计
- 支持用户行为分析和业务优化
2. 核心功能要求:
- 实时记录用户操作
- 支持按时间、用户、操作类型等维度查询
- 保留足够历史数据(建议至少90天)
- 敏感操作需记录操作前后的数据状态
二、系统设计
1. 日志数据结构
```json
{
"log_id": "唯一标识符",
"user_id": "用户ID",
"username": "用户名",
"operation_type": "操作类型(登录/下单/支付等)",
"operation_time": "操作时间(ISO8601格式)",
"ip_address": "操作IP",
"device_info": "设备信息",
"request_params": "请求参数(脱敏)",
"response_data": "响应数据(关键信息脱敏)",
"before_state": "操作前状态(可选)",
"after_state": "操作后状态(可选)",
"status": "操作状态(成功/失败)",
"error_message": "错误信息(如有)"
}
```
2. 技术架构选择
- 存储方案:Elasticsearch(快速检索) + MySQL(关系型数据备份)
- 采集方式:AOP切面编程 + 手动关键点记录
- 传输方式:异步消息队列(Kafka/RabbitMQ)
- 查询界面:独立管理后台或集成现有监控系统
三、开发实现
1. 后端实现(Spring Boot示例)
```java
// 日志注解定义
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
String operationType();
boolean saveBeforeState() default false;
boolean saveAfterState() default false;
}
// AOP切面实现
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private LogService logService;
@Around("@annotation(operationLog)")
public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
// 获取操作前状态(如果需要)
Object beforeState = null;
if(operationLog.saveBeforeState()) {
beforeState = getBeforeState(joinPoint);
}
// 执行原方法
Object result = joinPoint.proceed();
// 获取操作后状态(如果需要)
Object afterState = null;
if(operationLog.saveAfterState()) {
afterState = getAfterState(joinPoint, result);
}
// 构建日志对象
OperationLogDTO logDTO = buildLogDTO(joinPoint, operationLog, beforeState, afterState, result);
// 异步保存日志
logService.asyncSaveLog(logDTO);
return result;
}
// 其他辅助方法...
}
```
2. 日志服务实现
```java
@Service
public class LogServiceImpl implements LogService {
@Autowired
private LogMapper logMapper; // MySQL操作
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Async
@Override
public void asyncSaveLog(OperationLogDTO logDTO) {
// 1. 保存到MySQL
LogEntity logEntity = convertToEntity(logDTO);
logMapper.insert(logEntity);
// 2. 发送到Elasticsearch
Map esDoc = convertToESDoc(logDTO);
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(logDTO.getLogId())
.withObject(esDoc)
.build();
elasticsearchOperations.index(indexQuery, IndexCoordinates.of("operation_logs"));
// 3. 可选:发送到消息队列供其他系统消费
}
// 其他方法...
}
```
3. 前端查询界面
- 使用Vue/React开发独立管理页面
- 实现功能:
- 时间范围筛选
- 用户ID/用户名搜索
- 操作类型筛选
- 分页显示
- 详情查看(含操作前后状态对比)
四、关键实现细节
1. 敏感信息处理:
- 对用户密码、支付信息等敏感字段自动脱敏
- 使用AES加密存储部分敏感数据
2. 性能优化:
- 日志写入采用异步方式,避免影响主业务流程
- 批量写入Elasticsearch(每100条或每5秒)
- MySQL表按日期分区
3. 高可用设计:
- 日志消息队列持久化配置
- 多副本Elasticsearch集群
- 定期备份机制
五、测试方案
1. 单元测试:
- 测试日志注解是否正常工作
- 验证AOP切面是否正确拦截
- 检查数据转换是否正确
2. 集成测试:
- 模拟用户操作,验证日志是否完整记录
- 测试高并发场景下的日志写入性能
- 验证跨天日志分区是否正常
3. 压力测试:
- 模拟1000+TPS的日志写入
- 监控系统资源使用情况
- 验证Elasticsearch索引速度
六、部署与监控
1. 部署方案:
- 日志服务独立部署,避免影响主业务
- 使用Kubernetes管理日志服务Pod
- 配置合理的资源限制
2. 监控指标:
- 日志写入延迟
- 队列积压数量
- 存储空间使用率
- 查询响应时间
3. 告警规则:
- 连续5分钟日志写入失败
- 存储空间剩余不足20%
- 查询平均响应时间超过2秒
七、后续优化方向
1. 增加日志分析功能,生成用户行为报告
2. 实现异常操作自动告警
3. 添加日志压缩和归档策略
4. 支持更复杂的查询条件组合
5. 考虑引入日志采样机制,减少存储压力
八、开发时间线
| 阶段 | 内容 | 预计时长 |
|------|------|----------|
| 需求分析 | 明确日志记录范围和格式 | 3天 |
| 系统设计 | 架构设计、技术选型 | 5天 |
| 开发实现 | 核心功能开发 | 10天 |
| 测试验证 | 单元测试、集成测试 | 7天 |
| 部署上线 | 灰度发布、监控配置 | 3天 |
| 优化迭代 | 根据反馈调整 | 持续 |
该方案可根据快驴生鲜实际业务需求和技术栈进行调整,建议先实现核心功能,再逐步完善高级特性。