nx-monitor-sdk
v1.0.5
Published
轻量级前端监控SDK,专注Vue3应用的性能监控、错误追踪、用户行为分析
Downloads
18
Maintainers
Readme
nx-monitor-sdk
轻量级、高性能的前端监控 SDK,支持性能监控、错误追踪、用户行为分析和会话回放。
✨ 核心特性
- 性能监控: Web Vitals (FCP/LCP/FID/CLS/TTFB)、API 请求、资源加载
- 错误追踪: JS 错误、Promise 错误、资源错误、Vue/React 错误
- 行为分析: PV/UV、点击、路由、自定义事件、行为链路
- 会话回放: 完整记录用户操作,支持错误关联回放
- 轻量级: 核心包 < 50KB (gzip 压缩后 < 15KB)
- 开箱即用: 零配置快速接入,5 分钟集成
- 智能上报: 批量上报、失败重试、压缩传输
- 插件化: 按需加载,灵活扩展
- 隐私保护: 敏感信息脱敏、数据采样
- 框架支持: 原生 JS、Vue 3、React
📦 安装
npm install nx-monitor-sdk
# 或
yarn add nx-monitor-sdk
# 或
pnpm add nx-monitor-sdkCDN 引入:
<script src="https://unpkg.com/nx-monitor-sdk/dist/monitor.umd.js"></script>🚀 快速开始
Vue 3 项目(推荐)
// main.ts
import { createApp } from 'vue';
import Monitor from 'nx-monitor-sdk';
import App from './App.vue';
const app = createApp(App);
// 初始化监控
Monitor.init({
appId: 'your-app-id', // 必填:从管理平台获取
appKey: 'your-app-key', // 必填:从管理平台获取
serverUrl: 'http://localhost:3000/api/v1/report', // 必填:上报地址
version: '1.0.0', // 应用版本
debug: true, // 开发环境开启
// 会话回放配置
replay: {
enabled: true, // 启用会话回放
sampleRate: 1.0, // 采样率:100%
recordCrashOnly: false, // 是否只记录发生错误的会话
},
// 性能配置
performance: {
slowApiTime: 1000, // 慢接口阈值(ms)
slowResourceTime: 3000, // 慢资源阈值(ms)
},
});
// 配置 Vue 错误处理
app.config.errorHandler = (err, instance, info) => {
Monitor.captureException(err as Error, {
componentName: instance?.$options?.name,
errorInfo: info,
});
};
// 配置 Vue 警告处理
app.config.warnHandler = (msg, instance, trace) => {
Monitor.captureMessage(msg, {
level: 'warning',
componentName: instance?.$options?.name,
trace,
});
};
app.mount('#app');原生 JavaScript
<!DOCTYPE html>
<html>
<head>
<title>监控示例</title>
</head>
<body>
<button id="testBtn">测试按钮</button>
<script src="./node_modules/nx-monitor-sdk/dist/monitor.umd.js"></script>
<script>
// 初始化
Monitor.init({
appId: 'your-app-id',
appKey: 'your-app-key',
serverUrl: 'http://localhost:3000/api/v1/report',
version: '1.0.0',
debug: true,
});
// 设置用户信息
Monitor.setUserId('user_123');
Monitor.setUserInfo({
username: '张三',
role: 'admin',
});
// 监听按钮点击
document.getElementById('testBtn').addEventListener('click', () => {
Monitor.reportEvent('button_click', {
button: 'test',
page: window.location.pathname,
});
});
// 捕获异常
try {
// 业务代码
someFunction();
} catch (error) {
Monitor.captureException(error, {
extra: '额外信息',
});
}
</script>
</body>
</html>📚 完整文档
- Vue 3 使用指南 ⭐ 完整的 Vue 3 集成教程
- 示例代码 - 查看更多示例
- API 文档 - 所有 API 详细说明
🎯 核心功能
1. 性能监控 ⚡
Web Vitals 监控
自动监控 Web 性能核心指标:
// 自动上报,无需配置
// - FCP: 首次内容绘制
// - LCP: 最大内容绘制
// - FID: 首次输入延迟
// - CLS: 累积布局偏移
// - TTFB: 首字节时间API 请求监控
自动拦截 fetch 和 XMLHttpRequest:
// 自动监控所有 API 请求
// - 请求时长
// - 请求状态
// - 慢接口识别(超过阈值)
// - 失败接口追踪资源加载监控
自动监控静态资源加载:
// 自动监控
// - JS、CSS、图片、字体等资源
// - 加载时长
// - 加载失败
// - 慢资源识别2. 错误追踪 🐛
JS 错误
// 自动捕获 JS 错误
try {
throw new Error('测试错误');
} catch (error) {
// 自动捕获并上报
}
// 手动捕获
Monitor.captureException(new Error('自定义错误'), {
level: 'error',
extra: { key: 'value' },
});Promise 错误
// 自动捕获 Promise 拒绝
Promise.reject('Promise 错误'); // 自动上报
// 手动捕获
async function fetchData() {
try {
await api.getData();
} catch (error) {
Monitor.captureException(error);
}
}资源加载错误
// 自动捕获
// - <script> 加载失败
// - <link> 加载失败
// - <img> 加载失败Vue 错误
// 在 Vue 中配置
app.config.errorHandler = (err, instance, info) => {
Monitor.captureException(err as Error, {
componentName: instance?.$options?.name,
errorInfo: info,
});
};3. 用户行为分析 👤
页面访问 (PV/UV)
// 自动记录 PV
// 自动识别 UV(基于 deviceId)
// 手动上报页面访问
Monitor.reportEvent('page_view', {
page: '/home',
title: '首页',
});点击事件
// 自动捕获所有点击事件
// 记录:元素路径、元素文本、点击位置
// 手动上报点击
Monitor.reportEvent('button_click', {
button: 'submit',
page: '/checkout',
});路由切换
// Vue Router 示例
router.afterEach((to, from) => {
Monitor.reportEvent('route_change', {
from: from.path,
to: to.path,
title: to.meta.title,
});
});自定义事件
// 业务事件
Monitor.reportEvent('add_to_cart', {
productId: '12345',
productName: 'iPhone 15',
price: 5999,
});
// 操作事件
Monitor.reportEvent('search', {
keyword: 'Vue 3',
resultCount: 100,
});4. 会话回放 🎬
完整记录用户操作,支持回放查看:
Monitor.init({
appId: 'your-app-id',
appKey: 'your-app-key',
serverUrl: 'http://localhost:3000/api/v1/report',
// 会话回放配置
replay: {
enabled: true, // 启用回放
sampleRate: 1.0, // 采样率:100%(生产环境建议 0.1 - 0.3)
recordCrashOnly: false, // false: 全量记录,true: 只记录发生错误的会话
maskAllInputs: true, // 遮盖所有输入框内容(隐私保护)
blockClass: 'monitor-block', // 标记不记录的元素(添加此 class)
ignoreClass: 'monitor-ignore', // 标记忽略的元素
},
});回放功能:
- ✅ 完整记录 DOM 变化
- ✅ 记录鼠标移动、点击、滚动
- ✅ 记录输入框输入(可配置遮盖)
- ✅ 与错误关联,定位错误发生时刻
- ✅ 压缩传输,节省带宽
隐私保护:
<!-- 不记录敏感内容 -->
<input type="password" /> <!-- 自动遮盖 -->
<div class="monitor-block">敏感信息</div> <!-- 不记录 -->
<!-- 遮盖输入内容 -->
<input type="text" class="monitor-mask" /> <!-- 内容被 * 替代 -->🎛️ 配置选项
Monitor.init({
// ========== 必填配置 ==========
appId: 'your-app-id', // 应用 ID(从管理平台获取)
appKey: 'your-app-key', // 应用密钥(从管理平台获取)
serverUrl: 'http://localhost:3000/api/v1/report', // 上报地址
// ========== 基础配置 ==========
version: '1.0.0', // 应用版本(用于 SourceMap)
debug: false, // 调试模式(开启后输出日志)
enabled: true, // 是否启用监控
// ========== 性能配置 ==========
performance: {
slowApiTime: 1000, // 慢接口阈值(ms)
slowResourceTime: 3000, // 慢资源阈值(ms)
},
// ========== 会话回放配置 ==========
replay: {
enabled: true, // 是否启用回放
sampleRate: 1.0, // 采样率(0-1)
recordCrashOnly: false, // 只记录错误会话
maskAllInputs: true, // 遮盖所有输入
blockClass: 'monitor-block', // 不记录的元素 class
ignoreClass: 'monitor-ignore', // 忽略的元素 class
},
// ========== 上报配置 ==========
report: {
batch: {
enabled: true, // 批量上报
maxCacheSize: 10, // 最大缓存数
maxWaitTime: 5000, // 最大等待时间(ms)
},
compress: true, // 压缩上报数据
},
// ========== 功能开关 ==========
plugins: {
performance: true, // 性能监控
error: true, // 错误监控
behavior: true, // 行为监控
api: true, // API 监控
replay: true, // 会话回放
},
// ========== 钩子函数 ==========
hooks: {
beforeReport: (data) => {
// 上报前处理(返回 null 可阻止上报)
return data;
},
afterReport: (data, response) => {
// 上报成功回调
},
onReportError: (error) => {
// 上报失败回调
},
},
// ========== 隐私和安全 ==========
privacy: {
maskAllInputs: true, // 遮盖输入框
maskAllText: false, // 遮盖所有文本
ignoreUrls: ['/password', '/secret'], // 忽略的 URL
},
});📖 API 文档
初始化
Monitor.init(config: MonitorConfig): void用户信息
// 设置用户 ID
Monitor.setUserId(userId: string): void
// 设置用户信息
Monitor.setUserInfo(userInfo: Record<string, any>): void
// 清除用户信息
Monitor.clearUser(): void事件上报
// 上报自定义事件
Monitor.reportEvent(eventName: string, data?: Record<string, any>): void
// 捕获异常
Monitor.captureException(error: Error, context?: Record<string, any>): void
// 捕获消息
Monitor.captureMessage(message: string, context?: Record<string, any>): void性能测量
// 标记时间点
Monitor.mark(markName: string): void
// 测量两个时间点之间的duration
Monitor.measure(measureName: string, startMark: string, endMark: string): void控制方法
// 暂停监控
Monitor.pause(): void
// 恢复监控
Monitor.resume(): void
// 立即上报
Monitor.flush(): void
// 销毁实例
Monitor.destroy(): void💡 使用场景
场景 1:用户登录后设置用户信息
// Login.vue
const handleLogin = async () => {
const user = await loginApi(form);
// 设置用户信息
Monitor.setUserId(user.id);
Monitor.setUserInfo({
username: user.username,
email: user.email,
role: user.role,
vipLevel: user.vipLevel,
});
router.push('/dashboard');
};场景 2:监控页面停留时长
// Page.vue
import { onMounted, onUnmounted } from 'vue';
import Monitor from 'nx-monitor-sdk';
onMounted(() => {
Monitor.mark('page_enter');
});
onUnmounted(() => {
Monitor.mark('page_leave');
Monitor.measure('page_duration', 'page_enter', 'page_leave');
});场景 3:监控业务关键操作
const handleSubmitOrder = async () => {
const startTime = Date.now();
try {
const result = await submitOrder(orderData);
// 上报成功事件
Monitor.reportEvent('order_submit_success', {
orderId: result.orderId,
amount: orderData.amount,
paymentMethod: orderData.paymentMethod,
duration: Date.now() - startTime,
});
} catch (error) {
// 上报失败事件
Monitor.captureException(error, {
operation: 'submit_order',
orderData,
duration: Date.now() - startTime,
});
}
};场景 4:路由切换自动上报
// router/index.ts
import Monitor from 'nx-monitor-sdk';
router.beforeEach((to, from, next) => {
// 记录路由开始时间
Monitor.mark(`route_start_${to.path}`);
next();
});
router.afterEach((to, from) => {
// 上报路由切换
Monitor.reportEvent('route_change', {
from: from.path,
to: to.path,
toTitle: to.meta.title,
});
// 测量路由切换耗时
Monitor.mark(`route_end_${to.path}`);
Monitor.measure(
`route_${to.path}`,
`route_start_${to.path}`,
`route_end_${to.path}`
);
});场景 5:API 请求全局监控
// axios 拦截器
import axios from 'axios';
import Monitor from 'nx-monitor-sdk';
// 请求拦截
axios.interceptors.request.use((config) => {
config.metadata = { startTime: Date.now() };
return config;
});
// 响应拦截
axios.interceptors.response.use(
(response) => {
const duration = Date.now() - response.config.metadata.startTime;
// 慢接口告警
if (duration > 3000) {
Monitor.reportEvent('slow_api', {
url: response.config.url,
method: response.config.method,
duration,
});
}
return response;
},
(error) => {
Monitor.captureException(error, {
type: 'api_error',
url: error.config?.url,
method: error.config?.method,
});
return Promise.reject(error);
}
);🔍 调试技巧
开启调试模式
Monitor.init({
appId: 'your-app-id',
appKey: 'your-app-key',
serverUrl: 'http://localhost:3000/api/v1/report',
debug: true, // 👈 开启调试
});控制台输出:
[Monitor] Initialized successfully
[Monitor] Queued performance/web-vitals: { FCP: 1234, LCP: 2345 }
[Monitor] Sending 3 items...
[Monitor] Report success: { code: 0, message: 'ok' }查看上报数据
Monitor.init({
debug: true,
hooks: {
beforeReport: (data) => {
console.log('📤 即将上报:', data);
return data;
},
afterReport: (data, response) => {
console.log('✅ 上报成功:', data, response);
},
onReportError: (error) => {
console.error('❌ 上报失败:', error);
},
},
});手动触发上报
// 立即上报所有缓存数据
Monitor.flush();📊 数据查看
启动监控平台
1. 启动后端服务
cd monitor-sdk-node
docker-compose up -d
# 或
npm run dev2. 启动前端管理平台
cd monitor-sdk-client
npm run dev3. 访问平台
打开浏览器访问:http://localhost:5174
默认账号:
- 用户名:
admin - 密码:
admin123
查看监控数据
登录后可查看:
- 📊 Dashboard: 实时概览(PV、UV、错误数、性能指标)
- 🐛 错误监控: 错误列表、详情、堆栈、会话回放
- ⚡ 性能监控: Web Vitals、API 请求、资源加载
- 👤 用户行为: 页面访问、点击事件、自定义事件
- 📈 数据报表: 错误报表、性能报表、行为报表
- 🎬 会话回放: 用户操作录像
❓ 常见问题
Q1: 为什么看不到性能数据?
A: SDK 默认只上报慢接口和失败接口,可以降低阈值:
Monitor.init({
performance: {
slowApiTime: 500, // 降低到 500ms
slowResourceTime: 1000, // 降低到 1000ms
},
});Q2: 数据没有上报?
A: 检查以下几点:
- ✅ 开启
debug: true查看控制台日志 - ✅ 检查 Network 中的
/api/v1/report请求 - ✅ 确认
appId、appKey、serverUrl配置正确 - ✅ 批量上报需要满足条件(10 条或 5 秒),可调用
Monitor.flush()立即上报
Q3: 会话回放占用太多资源?
A: 优化建议:
- 降低采样率:
sampleRate: 0.1(只记录 10%) - 只记录错误:
recordCrashOnly: true - 遮盖敏感内容:
maskAllInputs: true
Monitor.init({
replay: {
enabled: true,
sampleRate: 0.1, // 只记录 10% 的会话
recordCrashOnly: true, // 只记录发生错误的会话
maskAllInputs: true, // 遮盖输入框
},
});Q4: 如何在控制台看到上报数据?
A: 使用钩子函数:
Monitor.init({
debug: true,
hooks: {
beforeReport: (data) => {
console.table(data); // 表格形式展示
return data;
},
afterReport: (data, response) => {
console.log('✅ 上报成功:', response);
},
},
});Q5: 支持哪些浏览器?
A:
- Chrome >= 90
- Firefox >= 88
- Safari >= 14
- Edge >= 90
📦 构建产物
dist/
├── monitor.esm.js # ES Module 格式
├── monitor.cjs.js # CommonJS 格式
├── monitor.umd.js # UMD 格式(可直接在浏览器使用)
├── types/ # TypeScript 类型定义
└── *.map # Source Map🛠️ 技术栈
- TypeScript - 类型安全
- web-vitals - Web 性能指标
- rrweb - 会话回放
- pako - gzip 压缩
- Vite - 构建工具
📚 相关文档
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
- Fork 项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交变更 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 创建 Pull Request
📄 License
MIT
快速开始:查看 Vue 3 使用指南 了解更多! 📖
维护者: Tank
最后更新: 2025-11-18
