web-monitor-tracking-component
v1.0.11
Published
一个轻量级的前端监控和埋点SDK,支持错误监控、性能监控、用户行为追踪和自定义事件上报。
Readme
Web Monitoring & Tracking SDK
一个轻量级的前端监控和埋点SDK,支持错误监控、性能监控、用户行为追踪和自定义事件上报。
安装
npm install watch-sdk --save功能特点
监控功能:
- 错误监控(JS异常、Promise拒绝、资源加载、API请求)
- 性能监控(首屏时间、页面加载、API响应时间)
- 白屏检测
- 页面录屏回放
- 用户行为追踪
埋点功能:
- PV/UV统计
- 用户点击行为追踪
- 表单提交监控
- 页面停留时长统计
- 自定义事件上报
- API性能指标采集
- 动态用户ID设置(✨ 新功能)
📋 ID 管理机制
🔑 三种 ID 的职责划分
| ID 类型 | 用途 | 管理方式 | 持久性 | 用户控制 | |---------|------|----------|--------|----------| | distinctId | 访问者唯一标识 | 系统自动管理 | localStorage 持久化 | ❌ 不可设置 | | deviceId | 设备指纹标识 | 系统计算生成 | 会话期间有效 | ❌ 不可设置 | | userId | 业务用户标识 | 开发者控制 | 可选持久化 | ✅ 可动态设置 |
🛡️ 系统自动管理的 ID
distinctId(访问者ID)
// ✅ 系统自动处理,无需配置
const tracker = new Tracker({
dsn: 'https://your-api.com',
apikey: 'your-api-key',
// distinctId 由系统自动生成和管理
});
// 系统会自动:
// 1. 检查 localStorage 中是否已存在
// 2. 不存在则生成新的 distinctId
// 3. 格式:vid_1703123456789_abc123def
// 4. 自动保存到 localStoragedeviceId(设备指纹)
// ✅ 基于设备特征自动计算
// 系统会自动:
// 1. 收集设备信息(userAgent、screen、platform等)
// 2. 使用 SHA-256 生成设备指纹
// 3. 相同设备始终生成相同的 deviceId
// 4. 不同设备生成不同的 deviceId👤 开发者可控制的 ID
userId(业务用户ID)
// ✅ 用户登录后设置
tracker.setUserId('user_12345');
// ✅ 用户登出时清除
tracker.setUserId(null);
// ✅ 获取当前用户ID
const currentUserId = tracker.getUserId();⚠️ 常见误区
❌ 错误做法
// ❌ 不要尝试传入 distinctId
const tracker = new Tracker({
dsn: 'https://your-api.com',
apikey: 'your-api-key',
distinctId: 'my-custom-id' // 此字段已移除
});
// ❌ 不要尝试设置 deviceId
// deviceId 是系统计算的设备指纹,无法手动设置✅ 正确做法
// ✅ 让系统自动管理 distinctId 和 deviceId
const tracker = new Tracker({
dsn: 'https://your-api.com',
apikey: 'your-api-key',
autoTrack: true,
enableHeatmap: true // 开启热力图功能,记录用户点击行为
});
// ✅ 只在必要时设置 userId
if (isUserLoggedIn) {
tracker.setUserId(getCurrentUserId());
}🎯 设计原理
- distinctId:确保每个访问者都有唯一标识,用于用户行为分析
- deviceId:识别设备特征,用于设备分析和反作弊
- userId:关联业务用户,用于用户画像和行为归因
这种设计确保了数据的唯一性、一致性和可靠性。
快速开始
基础用法
SDK使用 mode 字段控制启用哪些功能:
import sdk from 'watch-sdk';
// 同时启用监控和埋点功能
sdk.init({
dsn: 'https://your-server.com/api',
apikey: 'your-project-key',
mode: 'all', // 'monitoring', 'tracking', 'all'
// 注意:userId 现在不需要在初始化时提供,可以动态设置
// 监控特有配置
monitoring: {
silentRecordScreen: true
},
// 埋点特有配置
tracking: {
autoTrack: true,
enableHeatmap: true, // 🎯 开启热力图功能
sampling: { ratio: 1 }, // 采样率
maxCache: 20, // 缓存配置
apiFilter: {
excludeUrls: ['/api/heartbeat'] // 过滤配置
}
}
});
// 用户登录后动态设置用户ID
sdk.setUserId('user123');
// 用户注销时清空用户ID
sdk.setUserId(null);
// 获取当前用户ID
const currentUserId = sdk.getUserId();动态用户ID设置 ✨
在新版本中,您可以在用户登录后动态设置用户ID,无需在SDK初始化时提供:
// 1. 初始化SDK(无需userId)
sdk.init({
dsn: 'https://your-server.com/api',
apikey: 'your-project-key',
mode: 'tracking'
});
// 2. 用户登录成功后设置userId
async function handleUserLogin(username, password) {
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const userData = await response.json();
if (userData.success) {
// 动态设置用户ID
sdk.setUserId(userData.userId);
// 发送登录成功事件(自动包含userId)
sdk.trackCustomEvent('user_login', {
loginMethod: 'password',
userType: userData.userType
});
}
} catch (error) {
console.error('登录失败:', error);
}
}
// 3. 用户注销时清空userId
function handleUserLogout() {
// 发送注销事件(包含当前userId)
sdk.trackCustomEvent('user_logout', {
logoutReason: 'user_action'
});
// 清空用户ID
sdk.setUserId(null);
}
// 4. 检查当前用户状态
const userId = sdk.getUserId();
if (userId) {
console.log('当前用户ID:', userId);
} else {
console.log('用户未登录');
}userId 字段特性
- 全面覆盖:事件数据、设备信息、通用事件数据都包含
userId字段 - 动态设置:支持运行时动态设置和清空用户ID
- 数据一致性:所有模块同步更新用户ID
- 向后兼容:不影响现有代码的正常运行
userId vs distinctId
| 字段 | 说明 | 生成时机 | 用途 |
|------|------|----------|------|
| distinctId | 访客唯一标识 | SDK初始化时自动生成 | 区分不同访客,匿名用户追踪 |
| userId | 用户唯一标识 | 用户登录后手动设置 | 关联具体用户,登录用户追踪 |
Vue 中使用
import Vue from 'vue';
import sdk from 'watch-sdk';
Vue.use(sdk, {
dsn: 'https://your-server.com/api',
apikey: 'your-project-key',
mode: 'all'
});
// 在Vue组件中动态设置用户ID
export default {
methods: {
async login() {
// 登录逻辑...
const userData = await this.callLoginAPI();
// 设置用户ID
sdk.setUserId(userData.userId);
},
logout() {
// 清空用户ID
sdk.setUserId(null);
}
}
}