# MQTT通信日志系统开发方案

## 1. 项目概述

### 1.1 目标与意义

开发MQTT通信日志系统，用于完整记录单片机与服务器系统之间的所有MQTT消息通信。该系统具有以下价值：

- **通信可视化**：直观展示单片机与服务器之间的通信细节和消息内容
- **故障诊断**：为消息处理失败、设备离线等异常场景提供完整的调试信息
- **性能分析**：通过日志记录消息量、响应时间等指标，评估系统性能
- **安全审计**：记录所有通信活动，便于安全审计和问题追踪
- **业务分析**：通过通信数据分析设备使用模式和业务流程

### 1.2 系统定位

该系统为纯日志记录系统，**不干扰**正常的业务流程：

- 不消费消息队列中的数据
- 不修改消息内容或状态
- 仅作为"旁路监听者"记录通信过程
- 以非阻塞方式运行，不影响主业务性能

## 2. 技术架构设计

### 2.1 总体架构

![MQTT日志系统架构](https://placeholder-for-architecture-diagram.com)

系统采用"监听者模式"，不直接参与消息处理流程：

- **MQTT消息监听层**：订阅与主业务相同的Topic，但只读取不处理
- **日志记录层**：异步将消息内容写入数据库
- **查询展示层**：提供日志查询、过滤、导出功能的管理界面

### 2.2 数据库结构

已有数据表 `mqtt_communication_log` 包含了足够的字段设计：

```sql
CREATE TABLE `mqtt_communication_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志ID',
  `message_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '消息的唯一标识',
  `direction` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息方向: UPSTREAM (设备->服务器), DOWNSTREAM (服务器->设备)',
  `client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '相关的客户端ID',
  `topic` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'MQTT 主题',
  `payload_format` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'TEXT' COMMENT 'Payload 格式',
  `payload` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '消息原文',
  `qos` tinyint(4) NULL DEFAULT NULL COMMENT '消息QoS级别',
  `is_retained` tinyint(1) NULL DEFAULT NULL COMMENT '是否为保留消息',
  `log_timestamp` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '日志记录时间戳',
  `backend_processing_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '后端处理状态',
  `backend_processing_info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '后端处理附加信息',
  `related_session_id` bigint(20) NULL DEFAULT NULL COMMENT '关联的充电会话ID',
  `related_task_id` bigint(20) NULL DEFAULT NULL COMMENT '关联的机器人任务ID',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_log_timestamp`(`log_timestamp`) USING BTREE,
  INDEX `idx_topic`(`topic`(255)) USING BTREE,
  INDEX `idx_client_id`(`client_id`) USING BTREE,
  INDEX `idx_related_session_id`(`related_session_id`) USING BTREE,
  INDEX `idx_related_task_id`(`related_task_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MQTT通信日志表'
```

### 2.3 核心组件设计

#### 2.3.1 MQTT日志监听器

```java
@Component
public class MqttCommunicationLogger {
    // 依赖注入日志服务和MQTT客户端
}
```

#### 2.3.2 日志记录服务

```java
@Service
public class MqttLogService {
    // 异步记录消息到数据库
}
```

#### 2.3.3 日志查询Controller

```java
@RestController
@RequestMapping("/api/admin/mqtt-logs")
public class MqttLogController {
    // 提供日志查询API
}
```

## 3. 实现步骤

### 3.1 后端实现

1. **创建数据访问层**
   - 实现 `MqttCommunicationLogMapper` 接口
   - 实现 `MqttCommunicationLogService` 接口及其实现类

2. **实现消息监听与记录**
   - 创建独立的 MQTT 客户端用于日志记录
   - 配置该客户端订阅所有业务相关的主题
   - 实现监听回调，异步记录收到的消息
   - 为发送的消息添加拦截记录逻辑

3. **实现关联解析**
   - 解析消息内容，提取关联的会话ID、任务ID
   - 根据消息主题和内容推断消息类型和处理状态

4. **实现管理API**
   - 创建日志查询Controller
   - 实现分页查询、条件过滤、时间范围查询
   - 实现日志导出功能

### 3.2 前端实现

1. **日志查询页面**
   - 创建管理员专用的日志查询页面
   - 实现条件筛选表单（时间范围、客户端ID、主题等）
   - 实现分页表格展示日志记录

2. **日志详情展示**
   - 实现日志详情模态框
   - 格式化JSON消息内容，便于阅读
   - 显示相关的业务信息（会话、任务）链接

3. **日志分析功能**
   - 实现简单的统计分析（消息量、成功率等）
   - 提供日志导出功能

## 4. 技术实现细节

### 4.1 MQTT日志客户端配置

```java
@Configuration
public class MqttLoggerConfig {
    @Bean(name = "mqttLoggerClient")
    public MqttClient mqttLoggerClient() {
        // 配置单独的MQTT客户端用于日志记录
        // 与主业务使用相同的broker但不同的clientId
    }
}
```

### 4.2 消息记录实现

```java
@Component
public class MqttLogSubscriber implements MqttCallback {
    
    @Async
    public void messageArrived(String topic, MqttMessage message) {
        // 1. 解析消息，提取元数据
        // 2. 构建日志记录对象
        // 3. 异步保存到数据库
        // 注意：完全不干扰消息的正常传递
    }
}
```

### 4.3 发送消息记录

```java
@Aspect
@Component
public class MqttPublishAspect {
    
    @Around("execution(* com.yupi.project.mqtt.MqttService.publish*(..)) || execution(* com.yupi.project.mqtt.MqttService.sendCommand*(..))")
    public Object logMqttPublish(ProceedingJoinPoint joinPoint) throws Throwable {
        // 前置：记录发送前信息
        Object result = joinPoint.proceed(); // 执行原方法
        // 后置：记录发送后信息
        return result;
    }
}
```

### 4.4 业务关联解析

```java
@Component
public class MqttPayloadParser {
    
    public MqttLogBusinessInfo parsePayload(String topic, String payload) {
        // 根据主题和内容解析出业务相关信息
        // 例如：会话ID、任务ID、指令类型等
    }
}
```

## 5. 部署与配置

### 5.1 配置项

在 `application.yml` 中添加MQTT日志系统的配置：

```yaml
mqtt:
  logger:
    enabled: true
    client-id-prefix: logger-
    topics: 
      - charging/spot/+/status
      - charging/spot/+/command/#
      - charging/spot/+/heartbeat
    async:
      core-pool-size: 2
      max-pool-size: 5
      queue-capacity: 500
    retention:
      days: 30  # 日志保留天数
```

### 5.2 数据库维护

- 设计日志清理策略，避免数据过度膨胀
- 实现定时任务，清理超过保留期的日志数据
- 考虑按时间分区表策略，优化大量日志的存储和查询性能

## 6. 测试计划

### 6.1 功能测试

- 验证各类消息的正确记录
- 验证消息内容完整性
- 验证不同格式消息的解析效果
- 验证业务关联信息的正确提取

### 6.2 性能测试

- 高并发消息下的记录性能
- 验证日志记录对主业务的性能影响（应小于5%）
- 验证大数据量下的查询性能

### 6.3 稳定性测试

- 长时间运行测试
- 异常情况下的日志记录可靠性测试
- 系统重启后的连续性测试

## 7. 注意事项与风险

### 7.1 技术风险

- **性能影响**：确保日志记录不成为系统瓶颈
  - 解决方案：异步记录，独立线程池，必要时考虑消息缓冲
  
- **存储膨胀**：MQTT消息量大可能导致数据库快速增长
  - 解决方案：设置合理的日志保留策略，定期清理或归档

- **消息完整性**：某些异常情况可能导致日志不完整
  - 解决方案：增加重试机制，添加监控告警

### 7.2 业务风险

- **敏感信息**：日志可能包含敏感业务数据
  - 解决方案：实现字段级别的脱敏，严格控制日志访问权限

- **一致性**：日志状态与实际业务状态可能不一致
  - 解决方案：明确标注日志仅用于参考，不作为业务状态的权威来源

## 8. 后续优化方向

- 实现更复杂的消息分析功能
- 添加可视化图表，直观展示通信模式和趋势
- 实现异常模式的自动检测和告警
- 与系统监控平台集成，提供更全面的系统健康视图

## 9. 项目计划

| 阶段 | 内容 | 时间估计 |
|------|------|----------|
| 设计与准备 | 详细设计、环境准备 | 2天 |
| 后端开发 | 核心记录功能实现 | 3天 |
| 前端开发 | 日志查询界面实现 | 3天 |
| 测试与优化 | 功能测试、性能优化 | 2天 |
| 文档与部署 | 编写文档、系统部署 | 1天 |

**总计划时间**：约11个工作日 