# YUHAN-SDK **Repository Path**: westwest233/yuhan-sdk ## Basic Information - **Project Name**: YUHAN-SDK - **Description**: 一款面向 React / Vue 前端应用的监控 SDK,提供错误监控、性能分析、用户行为追踪、白屏检测与录屏回放能力。所有采集能力基于浏览器原生 API 实现,天然与框架无关,通过事件总线(EventBus)解耦各模块 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-08-15 - **Last Updated**: 2026-09-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # YuHan Monitor SDK 一款面向 React / Vue 前端应用的**监控 SDK**,提供错误监控、性能分析、用户行为追踪、白屏检测与录屏回放能力。所有采集能力基于浏览器原生 API 实现,天然与框架无关,通过事件总线(EventBus)解耦各模块。 ## 功能特性 ### 🚨 错误监控 - JavaScript 运行时错误捕获(`window.onerror`) - 未处理的 Promise 拒绝(`window.onunhandledrejection`) - 资源加载错误(`img` / `script` / `link`) - React ErrorBoundary / Vue errorHandler 集成 - Source Map 堆栈还原,定位源码真实位置 - 手动上报错误 `reportError` ### 📊 性能监控 - Web Vitals 核心指标:**LCP / CLS / INP / FID / FCP / TTFB** - 资源加载性能(`PerformanceObserver`) - 长任务检测(Long Task > 50ms) - 内存使用跟踪 - 手动上报自定义性能指标 ### 🖱️ 用户行为分析 - 点击事件追踪(捕获阶段) - 路由变化监控(pushState / hash / popstate) - 网络请求拦截(XHR / Fetch) - 控制台日志记录 - 面包屑轨迹(随错误上报,便于回溯操作路径) ### 🎬 录屏回放 - 基于 rrweb 的页面交互录制 - 错误关联:自动截取错误前后 N 秒录屏 - 隐私脱敏:密码框、敏感选择器自动打码 ### 🕳️ 白屏检测 - 视口采样点 + 根容器双重判定 - SPA 路由切换后自动重检 - 检测到白屏自动上报 ### 📤 数据上报 - 三种通道:Fetch(默认)/ Beacon / Image,带降级链 - 批量 + 定时上报,避免请求风暴 - 指数退避自动重试 - 采样率控制 - 调试模式 ## 安装 ```bash npm install yuhan-monitor-sdk ``` ## 快速开始 ### React ```jsx import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { init } from 'yuhan-monitor-sdk'; const monitor = init({ appKey: 'your-app-key', serverUrl: 'https://your-server.com/api/report', framework: { react: true }, advanced: { enableSessionReplay: true, sessionReplaySampleRate: 1 } }); // ESM 环境下需主动传入 React(解决 require('react') 失败) monitor.setReact(React); const { ErrorBoundary } = monitor; ReactDOM.createRoot(document.getElementById('root')).render( ); ``` ### Vue ```javascript import Vue from 'vue'; import App from './App.vue'; import { init } from 'yuhan-monitor-sdk'; const monitor = init({ appKey: 'your-app-key', serverUrl: 'https://your-server.com/api/report', framework: { vue: true } }); Vue.use(monitor); new Vue({ render: h => h(App) }).$mount('#app'); ``` ## 配置选项 ```javascript const config = { appKey: 'your-app-key', // 应用标识(必填) serverUrl: 'https://your-server.com/api/report', // 上报地址(必填) sampleRate: 1, // 采样率 0~1 debug: true, // 调试模式 error: { enable: true, captureGlobalErrors: true, // window.onerror capturePromiseRejections: true, // unhandledrejection captureResourceErrors: true // 资源加载错误 }, performance: { enable: true, captureWebVitals: true, // LCP/CLS/INP/FID/FCP/TTFB captureResourceTiming: true, captureLongTasks: true, captureMemory: true }, behavior: { enable: true, captureClicks: true, captureRouteChanges: true, captureNetworkRequests: true, captureConsole: false, maxBreadcrumbs: 20 }, advanced: { enableSessionReplay: true, // 录屏 sessionReplaySampleRate: 1, replayBeforeError: 30, // 错误前录制 N 秒 replayAfterError: 10, // 错误后继续录 N 秒 enableWhiteScreenDetection: true, // 白屏检测 blockSelector: '.monitor-block', ignoreClass: 'monitor-ignore' }, reporter: { batchSize: 5, // 批量大小 batchInterval: 5000, // 批量间隔 ms maxQueueSize: 20, // 最大队列 reportMethod: 'fetch', // fetch / beacon / image retryCount: 3, // 失败重试次数 retryDelay: 1000 // 重试初始延时 ms }, framework: { vue: false, react: false } }; ``` ## API ### 初始化 ```javascript import { init } from 'yuhan-monitor-sdk'; const monitor = init(config); ``` ### 用户管理 ```javascript monitor.setUserId('user123'); monitor.setUserData({ name: '张三', email: 'zhangsan@example.com' }); ``` ### 手动上报 ```javascript // 上报错误 monitor.reportError(new Error('自定义错误'), { page: 'home', component: 'Button' }); // 上报性能指标 monitor.reportPerformance({ type: 'custom', name: 'api-response-time', value: 120 }); // 添加面包屑 monitor.addBreadcrumb('custom', { message: '用户执行了操作' }); ``` ### 控制方法 ```javascript const config = monitor.getConfig(); monitor.setConfig({ debug: true }); const sessionId = monitor.getSessionId(); const breadcrumbs = monitor.getBreadcrumbs(); monitor.clearBreadcrumbs(); monitor.flush(); // 立即上报队列 monitor.destroy(); // 销毁 SDK,恢复所有被劫持的全局方法 ``` ## 本地开发测试 项目内置一套完整测试 Demo(`test-react-app`),需启动 3 个服务。 ### 启动方式 **终端 1 —— 构建 SDK** ```bash cd <项目根目录> npm run build ``` **终端 2 —— 启动监控后端(端口 3001)** ```bash cd <项目根目录> node test-server.js ``` **终端 3 —— 启动前端测试应用(端口 5173)** ```bash cd <项目根目录>/test-react-app npm install # 首次需安装依赖(基于 file:.. 链接到 SDK) npm run dev ``` ### 测试页面 浏览器访问 **http://localhost:5173** - **错误测试区**:触发 JS 错误 / Promise 拒绝 / 异步错误 - **性能测试区**:长任务、内存压力 - **Session Replay 区**:开始/停止录屏并上报 - **路由 / 网络 / 控制台**:验证行为采集 ### 查看上报数据 后端 API 端点: | 方法 | 端点 | 描述 | |------|------|------| | POST | `/api/report` | 接收错误和性能数据 | | POST | `/api/session-replay` | 接收录屏数据 | | GET | `/api/session-replay-list` | 获取录屏记录列表 | | GET | `/api/session-replay/:id` | 获取单条录屏完整数据 | | GET | `/replay` | 录屏回放页面 | | GET | `/api/data` | 获取所有接收的数据 | | DELETE | `/api/clear` | 清空所有数据 | 访问 **http://localhost:3001/api/data** 可查看所有上报数据: ```json { "errors": [...], "performance": [...], "behavior": [...], "sessionReplay": [...] } ``` ## 架构设计 基于**事件总线(EventBus)**实现模块解耦,采集器、上报器、高级模块之间不互相 import,只通过 `emit / on` 通信。 ``` ┌─────────────────────────────────────────────────────────┐ │ 浏览器原生 API │ │ window.onerror · unhandledrejection · addEventListener │ │ PerformanceObserver · rrweb · web-vitals │ └──────────────────────────┬──────────────────────────────┘ │ 采集 ┌──────────────────────────▼──────────────────────────────┐ │ EventBus 事件总线 │ │ error:captured · performance:* · behavior:* │ └───────┬────────────┬─────────────┬─────────────┬────────┘ │ │ │ │ DataReporter SourceMapParser SessionReplay 白屏检测 (上报) (堆栈还原) (录屏标记) (错误源) ``` 核心设计亮点: - **统一错误出口**:无论错误来自 js / promise / resource / 白屏,都统一 `emit('error:captured')` - **同步取数**:EventBus 的 `emit` 支持同步返回监听器结果,上报器可同步取回面包屑 / sessionId - **Monkey-Patching 可恢复**:所有被劫持的全局方法(onerror / fetch / console 等)在 `destroy()` 时恢复,不污染业务环境 ## 项目结构 ``` ├── src/ │ ├── core/ # 核心 │ │ ├── index.js # 主入口 │ │ ├── config.js # 配置管理 │ │ └── eventBus.js # 事件总线(SDK 神经系统) │ ├── collector/ # 数据采集器 │ │ ├── errorCollector.js # 错误采集 │ │ ├── performanceCollector.js # 性能采集 │ │ └── behaviorCollector.js # 行为采集(面包屑) │ ├── advanced/ # 高级功能 │ │ ├── sessionReplay.js # 录屏回放 │ │ ├── whiteScreenDetector.js# 白屏检测 │ │ └── sourceMapParser.js # Source Map 解析 │ ├── reporter/ # 数据上报 │ │ └── dataReporter.js # 上报器(批量/重试/降级) │ ├── framework/ # 框架集成 │ │ ├── reactIntegration.js │ │ └── vueIntegration.js │ └── index.js # SDK 门面(单例) ├── test-server.js # 本地监控后端 ├── replay.html # 录屏回放页 └── test-react-app/ # React 测试 Demo ``` ## 隐私保护 - SDK 不收集用户敏感个人信息 - 录屏默认对密码框脱敏 - 可通过选择器排除特定元素 ```javascript const config = { advanced: { maskAllInputs: true, blockSelector: '.private-info, [data-private]', ignoreClass: 'no-monitor' } }; ``` ## License MIT