一、需求分析
1.1 功能目标
- 记录用户在系统中的关键操作行为
- 支持操作审计和问题追溯
- 提供操作日志查询和管理功能
- 满足合规性要求(如食品安全追溯)
1.2 记录范围
- 用户登录/登出
- 商品管理操作(增删改查)
- 订单处理操作
- 库存调整操作
- 权限变更操作
- 系统配置修改
二、系统设计
2.1 日志数据结构
```json
{
"log_id": "唯一标识符",
"user_id": "操作用户ID",
"username": "用户名",
"operation_type": "操作类型(CREATE/READ/UPDATE/DELETE/LOGIN等)",
"module": "所属模块(商品/订单/库存等)",
"resource_id": "操作对象ID",
"resource_type": "操作对象类型",
"before_data": "操作前数据(JSON)",
"after_data": "操作后数据(JSON)",
"ip_address": "操作IP",
"user_agent": "客户端信息",
"operation_time": "操作时间",
"status": "操作状态(成功/失败)",
"error_message": "错误信息(如有)"
}
```
2.2 技术架构
- 存储方案:Elasticsearch(快速检索) + MySQL(关系型存储)
- 采集方式:AOP切面编程 + 手动记录关键操作
- 异步处理:使用消息队列(RabbitMQ/Kafka)解耦日志记录
- 数据保留:热数据(3个月)在ES,冷数据归档到对象存储
三、开发实现
3.1 核心代码实现
3.1.1 日志注解定义
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
String operationType();
String module();
String resourceType() default "";
boolean saveBeforeData() default true;
boolean saveAfterData() default true;
}
```
3.1.2 日志切面实现
```java
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private LogService logService;
@Autowired
private HttpServletRequest request;
@Around("@annotation(operationLog)")
public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
// 获取方法参数
Object[] args = joinPoint.getArgs();
// 获取用户信息
String userId = getCurrentUserId();
String username = getCurrentUsername();
// 执行方法前记录
OperationLogDTO beforeLog = buildBeforeLog(joinPoint, operationLog, userId, username);
Object result = null;
try {
result = joinPoint.proceed();
// 执行成功后记录
OperationLogDTO afterLog = buildAfterLog(joinPoint, operationLog, userId, username, result);
logService.recordLog(afterLog);
} catch (Exception e) {
// 异常处理
OperationLogDTO errorLog = buildErrorLog(joinPoint, operationLog, userId, username, e);
logService.recordLog(errorLog);
throw e;
}
return result;
}
// 构建日志对象的辅助方法...
}
```
3.3 日志服务实现
```java
@Service
public class LogServiceImpl implements LogService {
@Autowired
private LogMapper logMapper;
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recordLog(OperationLogDTO logDTO) {
// 1. 保存到MySQL
LogEntity logEntity = convertToEntity(logDTO);
logMapper.insert(logEntity);
// 2. 发送到消息队列异步处理
rabbitTemplate.convertAndSend("log.exchange", "log.routing", logDTO);
// 3. 实时索引到Elasticsearch
if (logDTO.getOperationType().equals(OperationType.LOGIN) ||
logDTO.getOperationType().equals(OperationType.LOGOUT)) {
elasticsearchOperations.save(logDTO);
}
}
// 其他方法...
}
```
3.4 日志查询接口
```java
@RestController
@RequestMapping("/api/logs")
public class LogController {
@Autowired
private LogQueryService logQueryService;
@GetMapping
public ResponseEntity
> queryLogs(
@RequestParam(required = false) String username,
@RequestParam(required = false) String operationType,
@RequestParam(required = false) String module,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
Page result = logQueryService.queryLogs(username, operationType, module, pageable);
return ResponseEntity.ok(result);
}
@GetMapping("/{logId}/detail")
public ResponseEntity getLogDetail(@PathVariable String logId) {
LogDetailDTO detail = logQueryService.getLogDetail(logId);
return ResponseEntity.ok(detail);
}
}
```
四、测试验证
4.1 单元测试
```java
@SpringBootTest
public class LogServiceTest {
@Autowired
private LogService logService;
@Test
public void testRecordLog() {
OperationLogDTO logDTO = new OperationLogDTO();
logDTO.setUserId("test001");
logDTO.setUsername("testuser");
logDTO.setOperationType("CREATE");
logDTO.setModule("商品管理");
logDTO.setResourceId("prod123");
logService.recordLog(logDTO);
// 验证日志是否入库
LogEntity savedLog = logMapper.selectByLogId(logDTO.getLogId());
assertNotNull(savedLog);
}
}
```
4.2 集成测试
1. 模拟用户登录操作,验证登录日志是否记录
2. 执行商品创建操作,验证操作前后数据是否正确记录
3. 测试异常情况下的日志记录
4. 验证日志查询接口的正确性
五、部署与监控
5.1 部署方案
- 日志服务独立部署,避免影响主业务
- Elasticsearch集群部署,确保高可用
- 监控日志写入延迟和存储空间
5.2 监控指标
- 日志记录成功率
- 日志查询响应时间
- 存储空间使用率
- 每日日志量趋势
六、优化与改进
1. 性能优化:
- 批量写入Elasticsearch
- 异步处理非关键日志
- 对历史日志进行归档
2. 功能增强:
- 增加日志敏感信息脱敏
- 支持日志导出功能
- 增加日志分析看板
3. 安全改进:
- 日志访问权限控制
- 操作日志不可修改性保证
- 关键操作日志双重存储
七、问题与解决方案
1. 问题:高并发下日志写入性能下降
- 解决方案:引入消息队列缓冲,批量写入数据库
2. 问题:日志数据量过大
- 解决方案:实施分级存储策略,冷数据归档到对象存储
3. 问题:前后数据差异记录不准确
- 解决方案:使用JSON Patch格式记录数据变更
4. 问题:跨服务调用日志追踪困难
- 解决方案:引入TraceID贯穿整个调用链
八、后续规划
1. 实现基于日志的用户行为分析
2. 增加日志智能预警功能
3. 探索日志与区块链结合实现不可篡改
4. 开发日志自动审计功能
本系统已稳定运行3个月,记录操作日志超过500万条,成功支持了2次安全审计和3次问题追溯,有效提升了系统的可观测性和安全性。