228 lines
10 KiB
Markdown
228 lines
10 KiB
Markdown
# Light-Sentry 轻量级前端监控系统 - 架构设计文档
|
||
|
||
## 一、设计理念
|
||
|
||
### 1.1 核心原则
|
||
|
||
- **轻量优先**:SDK < 10KB (gzip),服务端单节点可运行
|
||
- **插件化架构**:核心极小,功能通过插件扩展,按需加载
|
||
- **性能友好**:不阻塞主线程,不影响页面性能
|
||
- **易于部署**:docker-compose up 一键启动,无需复杂运维
|
||
- **兼容 Sentry**:接口兼容 Sentry 协议,可平滑迁移
|
||
|
||
### 1.2 设计目标
|
||
|
||
| 指标 | 目标值 | 说明 |
|
||
|------|--------|------|
|
||
| SDK 核心体积 | < 5KB gzip | 只含事件总线和上报 |
|
||
| SDK 完整体积 | < 15KB gzip | 含错误+性能+网络插件 |
|
||
| 单节点承载 | 10万+ 事件/天 | 1C2G 服务器 |
|
||
| 部署时间 | < 5 分钟 | docker-compose 一键部署 |
|
||
| 数据延迟 | < 30 秒 | 从上报到可查询 |
|
||
|
||
---
|
||
|
||
## 二、整体架构
|
||
|
||
### 2.1 架构图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 前端 SDK │
|
||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐ │
|
||
│ │ Error │ │ Perf │ │ Network │ │ Behavior │ │
|
||
│ │ Plugin │ │ Plugin │ │ Plugin │ │ Plugin │ │
|
||
│ └────┬────┘ └────┬────┘ └────┬────┘ └──────┬───────┘ │
|
||
│ └─────────────┴─────────────┴──────────────┘ │
|
||
│ │ │
|
||
│ ┌─────┴─────┐ │
|
||
│ │ Core │ │
|
||
│ │ (EventBus │ │
|
||
│ │ + Queue │ │
|
||
│ │ + Report)│ │
|
||
│ └─────┬─────┘ │
|
||
└──────────────────────────┼───────────────────────────────────┘
|
||
│ HTTP (beacon / fetch / img)
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Nginx 反向代理 │
|
||
│ 限流 · CORS · 负载均衡 · SSL 卸载 │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ API 接入层 (Node.js) │
|
||
│ ┌───────────────────────────────────────────────────────┐ │
|
||
│ │ 1. DSN 认证 (publicKey 校验) │ │
|
||
│ │ 2. 协议解析 (envelope / store / 自定义) │ │
|
||
│ │ 3. 数据清洗 (脱敏、过滤、去重) │ │
|
||
│ │ 4. 错误指纹计算 │ │
|
||
│ │ 5. 内存队列 + 批量写入 │ │
|
||
│ └───────────────────────────────────────────────────────┘ │
|
||
└──────────┬───────────────────────────┬──────────────────────┘
|
||
▼ ▼
|
||
┌─────────────────────┐ ┌───────────────────────┐
|
||
│ Loki (日志) │ │ MySQL (聚合数据) │
|
||
│ - 原始错误堆栈 │ │ - 项目配置 │
|
||
│ - 性能指标明细 │ │ - 错误聚合统计 │
|
||
│ - 用户行为日志 │ │ - 性能指标趋势 │
|
||
│ 保留: 7-30 天 │ │ - 告警规则 │
|
||
└─────────────────────┘ │ - 用户管理 │
|
||
└───────────┬───────────┘
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 查询 & 展示层 │
|
||
│ ┌──────────────┐ ┌──────────┐ ┌──────────────────────┐ │
|
||
│ │ 管理后台 │ │ 告警引擎 │ │ Grafana 仪表盘 │ │
|
||
│ │ (原生 JS) │ │ (规则引擎)│ │ (复用现有工具) │ │
|
||
│ │ - 项目管理 │ │ - 规则 │ │ - 错误趋势图 │ │
|
||
│ │ - 错误查询 │ │ - 收敛 │ │ - 性能仪表盘 │ │
|
||
│ │ - 性能分析 │ │ - 通知 │ │ - 自定义面板 │ │
|
||
│ └──────────────┘ └──────────┘ └──────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.2 模块职责
|
||
|
||
| 层级 | 模块 | 职责 | 技术选型 |
|
||
|------|------|------|----------|
|
||
| 采集层 | 前端 SDK | 数据采集、队列、上报 | TypeScript + 插件化 |
|
||
| 接入层 | API Server | 认证、解析、清洗、入队 | Node.js + Express |
|
||
| 存储层 | Loki | 原始日志存储 | Grafana Loki |
|
||
| 存储层 | MySQL | 聚合数据、配置、用户 | MySQL 8.0 / SQLite |
|
||
| 计算层 | 聚合服务 | 错误聚合、性能统计 | 定时任务 / 实时聚合 |
|
||
| 计算层 | 告警引擎 | 规则匹配、告警通知 | 内置规则引擎 |
|
||
| 展示层 | 管理后台 | 项目管理、数据查询 | 原生 HTML + JS |
|
||
| 展示层 | Grafana | 数据可视化 | Grafana |
|
||
|
||
---
|
||
|
||
## 三、数据流
|
||
|
||
### 3.1 错误上报流程
|
||
|
||
```
|
||
前端触发错误
|
||
↓
|
||
ErrorPlugin 捕获
|
||
↓
|
||
封装为标准事件格式
|
||
↓
|
||
加入内存队列
|
||
↓
|
||
批量/定时/页面隐藏 触发上报
|
||
↓
|
||
sendBeacon / fetch / img 标签
|
||
↓
|
||
Nginx (限流 + CORS)
|
||
↓
|
||
API Server
|
||
├─ DSN 认证
|
||
├─ envelope 解析
|
||
├─ 数据清洗 (脱敏IP、UA)
|
||
├─ 计算错误指纹
|
||
└─ 写入内存队列
|
||
↓
|
||
批量消费
|
||
├─ 写入 Loki (原始数据)
|
||
└─ 更新 MySQL 聚合表
|
||
↓
|
||
Grafana / 管理后台 查询
|
||
↓
|
||
告警引擎 检测规则
|
||
↓
|
||
触发通知 (Webhook / 邮件)
|
||
```
|
||
|
||
### 3.2 性能指标流程
|
||
|
||
```
|
||
PerformancePlugin 监听性能指标
|
||
↓
|
||
(FP / FCP / LCP / CLS / TTI / Long Task)
|
||
↓
|
||
采样过滤 (默认 10% 采样率)
|
||
↓
|
||
批量上报
|
||
↓
|
||
API Server 接收
|
||
├─ 数据校验
|
||
└─ 写入 Loki
|
||
↓
|
||
定时聚合任务 (每 5 分钟)
|
||
├─ 计算 P50 / P90 / P95 / P99
|
||
├─ 按项目 + 页面 + 小时 聚合
|
||
└─ 写入 MySQL 性能表
|
||
↓
|
||
Grafana 展示趋势图
|
||
```
|
||
|
||
---
|
||
|
||
## 四、技术选型说明
|
||
|
||
### 4.1 为什么用 Loki 而不是 ES/ClickHouse?
|
||
|
||
| 特性 | Loki | Elasticsearch | ClickHouse |
|
||
|------|------|---------------|------------|
|
||
| 部署复杂度 | 极低(单二进制) | 高(需调优) | 中 |
|
||
| 资源消耗 | 低(内存 + 磁盘) | 高(内存密集) | 中高 |
|
||
| 查询性能 | 中等(日志足够) | 高 | 极高 |
|
||
| 全文检索 | 支持(Label + grep) | 强大 | 支持 |
|
||
| Grafana 集成 | 原生 | 需配置 | 需配置 |
|
||
| 适合场景 | 日志、错误追踪 | 全文检索、复杂分析 | OLAP、大数据量 |
|
||
|
||
**结论**:轻量级监控,Loki 足够用,运维成本最低,和 Grafana 集成最好。
|
||
|
||
### 4.2 为什么用 MySQL 存聚合数据?
|
||
|
||
- 成熟稳定,运维简单
|
||
- 聚合后数据量不大(每天几千~几万行)
|
||
- 事务支持,数据一致性好
|
||
- 管理后台查询方便
|
||
- 小项目甚至可以用 SQLite,零运维
|
||
|
||
### 4.3 为什么前端用原生 JS?
|
||
|
||
- 后台页面不复杂,原生 JS 足够
|
||
- 无构建流程,修改即生效
|
||
- 体积小,加载快
|
||
- 不依赖前端框架生态,长期维护成本低
|
||
|
||
---
|
||
|
||
## 五、与现有 Light-Sentry 的关系
|
||
|
||
### 5.1 现有能力
|
||
|
||
- ✅ Sentry 兼容接口(store / envelope)
|
||
- ✅ Loki 原始日志存储
|
||
- ✅ Grafana 仪表盘
|
||
- ✅ 项目管理后台
|
||
- ✅ Docker Compose 一键部署
|
||
- ✅ NEL (Network Error Logging) 支持
|
||
|
||
### 5.2 待完善能力
|
||
|
||
- 🚧 自研轻量 SDK
|
||
- 🚧 错误指纹聚合
|
||
- 🚧 性能指标聚合
|
||
- 🚧 告警引擎
|
||
- 🚧 源 map 解析
|
||
- 🚧 用户会话追踪
|
||
- 🚧 行为分析插件
|
||
|
||
---
|
||
|
||
## 六、文档目录
|
||
|
||
```
|
||
docs/
|
||
├── 00-architecture.md # 本文档 - 整体架构
|
||
├── 01-sdk-design.md # 前端 SDK 设计
|
||
├── 02-api-server.md # 服务端接入层设计
|
||
├── 03-data-aggregation.md # 数据聚合与存储设计
|
||
├── 04-alert-engine.md # 告警引擎设计
|
||
├── 05-admin-dashboard.md # 管理后台与可视化设计
|
||
└── 06-deployment.md # 部署与运维设计
|
||
```
|