WebTracing 是一个基于 JavaScript 的前端埋点SDK,为前端项目提供全面的监控解决方案。
WebTracing 努力为你的前端项目提供8大监控手段:
# 核心实现包 - 原生JavaScript
pnpm install @web-tracing/core
# Vue2专用版本
pnpm install @web-tracing/vue2
# Vue3专用版本
pnpm install @web-tracing/vue3
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebTracing Demotitle>
head>
<body>
<script src="https://cdn.jsdelivr.net/npm/@web-tracing/core">script>
<script>
webtracing.init({
appName: 'my-app',
debug: true,
pv: true,
performance: true,
error: true,
event: true,
cacheMaxLength: 10,
cacheWatingTime: 1000,
userUuid: 'init_userUuid',
scopeError: true,
tracesSampleRate: 0.5,
ignoreErrors: ['111', /^promise/, /.*split is not .* function/],
ignoreRequest: ['111', /normal/],
beforePushEventList(data) {
return data
},
beforeSendData(data) {
// 返回false代表sdk不再发送
return data
},
afterSendData(data) {
console.log('数据发送完成', data)
}
})
script>
body>
html>
import WebTracing from '@web-tracing/vue2'
Vue.use(WebTracing, {
dsn: '/trackweb',
appName: 'vue2-app',
debug: true,
pv: true,
performance: true,
error: true,
event: true,
cacheMaxLength: 10,
cacheWatingTime: 1000,
userUuid: 'init_userUuid',
scopeError: true,
tracesSampleRate: 0.5,
ignoreErrors: ['111', /^promise/, /.*split is not .* function/],
ignoreRequest: [/getAllTracingList/, /cleanTracingList/],
beforePushEventList(data) {
const arr = ['intersection', 'click']
data.forEach(item => {
if (arr.includes(item.eventType)) {
// 触发自定义逻辑
window.vm.sendMessage()
}
})
return data
},
beforeSendData(data) {
// 数据发送前处理
return data
},
afterSendData(data) {
// 数据发送后处理
console.log('Vue2数据发送完成', data)
}
})
import { createApp } from 'vue'
import WebTracing from '@web-tracing/vue3'
import App from './App.vue'
const app = createApp(App)
app.use(WebTracing, {
dsn: '/trackweb',
appName: 'vue3-app',
debug: true,
pv: true,
performance: true,
error: true,
event: true,
cacheMaxLength: 10,
cacheWatingTime: 1000,
ignoreRequest: [
/getAllTracingList/,
/cleanTracingList/,
/getBaseInfo/,
/getSourceMap/
],
afterSendData(data) {
console.log('Vue3数据发送完成', data)
}
})
app.mount('#app')
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
dsn |
string | - | 数据上报接口地址 |
appName |
string | - | 应用名称,用于区分不同项目 |
debug |
boolean | false | 开启调试模式,控制台输出详细日志 |
userUuid |
string | - | 用户唯一标识符 |
配置项 | 类型 | 说明 |
---|---|---|
pv |
boolean | 页面访问统计 (Page View) |
performance |
boolean | 性能监控开关 |
error |
boolean | 错误监控开关 |
event |
boolean | 事件监控开关 |
scopeError |
boolean | 作用域错误捕获 |
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
cacheMaxLength |
number | 10 | 缓存队列最大长度 |
cacheWatingTime |
number | 1000 | 缓存等待时间(ms) |
tracesSampleRate |
number | 1.0 | 数据采样率 (0-1) |
{
// 忽略的错误
ignoreErrors: [
'111', // 字符串匹配
/^promise/, // 正则匹配
/.*split is not .* function/ // 正则匹配
],
// 忽略的请求
ignoreRequest: [
/getAllTracingList/,
/cleanTracingList/,
/getBaseInfo/
]
}
{
// 事件入队前处理
beforePushEventList(data) {
// 可对数据进行预处理
console.log('事件入队:', data)
return data
},
// 数据发送前处理
beforeSendData(data) {
// 返回false阻止发送
console.log('即将发送:', data)
return data
},
// 数据发送后处理
afterSendData(data) {
console.log('发送完成:', data)
}
}
自动捕获用户交互行为:
// 自动监控的事件类型
const eventTypes = [
'click', // 点击事件
'input', // 输入事件
'change', // 表单变化
'submit', // 表单提交
'scroll', // 滚动事件
'resize' // 窗口调整
]
// 手动触发事件
webtracing.track('custom_event', {
category: 'user_action',
action: 'button_click',
label: 'header_login_btn',
value: 1
})
监控页面加载和运行性能:
// 监控指标
const performanceMetrics = {
FCP: 'First Contentful Paint', // 首次内容绘制
LCP: 'Largest Contentful Paint', // 最大内容绘制
FID: 'First Input Delay', // 首次输入延迟
CLS: 'Cumulative Layout Shift', // 累积布局偏移
TTFB: 'Time to First Byte', // 首字节时间
FP: 'First Paint' // 首次绘制
}
// 自定义性能标记
webtracing.markStart('api_call')
// ... 执行API调用
webtracing.markEnd('api_call')
自动捕获和上报错误:
// 自动捕获的错误类型
const errorTypes = [
'JavaScript运行时错误',
'Promise未捕获错误',
'资源加载错误',
'网络请求错误',
'Vue组件错误' // Vue版本
]
// 手动上报错误
webtracing.captureException(new Error('自定义错误'), {
tags: {
component: 'UserProfile',
action: 'save_data'
},
extra: {
userId: '12345',
timestamp: Date.now()
}
})
监控HTTP请求状态和性能:
// 自动监控
const requestMetrics = {
url: 'string', // 请求URL
method: 'string', // 请求方法
status: 'number', // 响应状态码
duration: 'number', // 请求耗时
size: 'number', // 响应大小
timestamp: 'number' // 请求时间戳
}
// 手动上报请求信息
webtracing.trackRequest({
url: '/api/user/profile',
method: 'GET',
status: 200,
duration: 350,
success: true
})
监控静态资源加载情况:
// 监控的资源类型
const resourceTypes = [
'script', // JS文件
'stylesheet', // CSS文件
'img', // 图片
'font', // 字体
'fetch', // Fetch请求
'xmlhttprequest' // XHR请求
]
// 资源性能指标
const resourceMetrics = {
name: 'string', // 资源名称
type: 'string', // 资源类型
duration: 'number', // 加载时长
size: 'number', // 资源大小
transferSize: 'number', // 传输大小
encodedBodySize: 'number' // 编码后大小
}
SPA路由切换追踪:
// Vue Router 集成示例
router.beforeEach((to, from, next) => {
webtracing.trackPageView({
path: to.path,
name: to.name,
params: to.params,
query: to.query,
referrer: from.path
})
next()
})
// 手动路由追踪
webtracing.trackRoute({
from: '/home',
to: '/profile',
duration: 150,
trigger: 'navigation'
})
元素可见性监控:
// 自动曝光监控 (需要添加data属性)
<div data-track-exposure="banner_ad" data-exposure-ratio="0.5">
广告内容
</div>
// 手动曝光监控
webtracing.trackExposure({
element: 'product_card_123',
ratio: 0.8,
duration: 2000,
position: { x: 100, y: 200 }
})
// 配置曝光参数
{
intersectionRatio: 0.5, // 可见比例阈值
intersectionTime: 1000 // 持续时间阈值
}
// 生产环境配置
const productionConfig = {
dsn: 'https://api.your-domain.com/tracking',
appName: 'your-app-name',
debug: false,
// 开启核心功能
pv: true,
performance: true,
error: true,
event: true,
// 优化缓存策略
cacheMaxLength: 20,
cacheWatingTime: 5000,
// 设置采样率 (生产环境建议降低)
tracesSampleRate: 0.1,
// 过滤无关错误
ignoreErrors: [
/Script error/,
/ResizeObserver loop limit exceeded/,
/Non-Error promise rejection captured/
],
// 过滤内部请求
ignoreRequest: [
/\/tracking/,
/\/health-check/,
/\/metrics/
]
}
// 开发环境配置
const developmentConfig = {
...productionConfig,
debug: true,
tracesSampleRate: 1.0
}
// 用户登录后更新标识
function onUserLogin(user) {
webtracing.setUser({
id: user.id,
email: user.email,
name: user.name,
role: user.role
})
}
// 用户登出时清理
function onUserLogout() {
webtracing.clearUser()
}
// 设置用户属性
webtracing.setUserProperty('vip_level', 'gold')
// 业务关键指标追踪
const trackBusinessMetrics = {
// 购买转化
trackPurchase(orderId, amount, currency) {
webtracing.track('purchase', {
order_id: orderId,
amount: amount,
currency: currency,
timestamp: Date.now()
})
},
// 搜索行为
trackSearch(query, resultCount) {
webtracing.track('search', {
query: query,
result_count: resultCount,
search_type: 'product'
})
},
// 功能使用
trackFeatureUsage(feature, action) {
webtracing.track('feature_usage', {
feature: feature,
action: action,
user_type: 'premium'
})
}
}
// 全局错误处理
window.addEventListener('error', (event) => {
// 添加更多上下文信息
webtracing.captureException(event.error, {
tags: {
source: 'global_handler',
filename: event.filename,
lineno: event.lineno,
colno: event.colno
},
extra: {
userAgent: navigator.userAgent,
url: window.location.href,
timestamp: Date.now()
}
})
})
// Promise错误处理
window.addEventListener('unhandledrejection', (event) => {
webtracing.captureException(event.reason, {
tags: {
source: 'unhandled_promise'
}
})
})
// 关键渲染路径监控
function trackCriticalRendering() {
// 监控首屏渲染
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.entryType === 'paint') {
webtracing.track('paint_timing', {
name: entry.name,
startTime: entry.startTime,
duration: entry.duration
})
}
})
})
observer.observe({ entryTypes: ['paint'] })
}
// 自定义性能指标
function trackCustomMetrics() {
// 页面加载完成时间
window.addEventListener('load', () => {
const loadTime = performance.now()
webtracing.track('page_load_complete', {
load_time: loadTime,
page_url: window.location.href
})
})
}
const eventData = {
eventType: 'click', // 事件类型
eventId: 'unique_id', // 事件唯一ID
timestamp: 1640995200000, // 时间戳
userId: 'user_123', // 用户ID
sessionId: 'session_456', // 会话ID
pageUrl: '/home', // 页面URL
element: { // 元素信息
tagName: 'button',
className: 'btn-primary',
textContent: '登录',
attributes: {}
},
position: { // 位置信息
x: 100,
y: 200
},
extra: {} // 额外数据
}
const performanceData = {
type: 'performance',
timestamp: 1640995200000,
metrics: {
FCP: 1200, // 首次内容绘制
LCP: 2500, // 最大内容绘制
FID: 50, // 首次输入延迟
CLS: 0.1, // 累积布局偏移
TTFB: 300, // 首字节时间
domContentLoaded: 1500, // DOM解析完成
loadComplete: 3000 // 页面加载完成
},
navigation: {
type: 'navigate', // 导航类型
redirectCount: 0 // 重定向次数
}
}
const errorData = {
type: 'error',
timestamp: 1640995200000,
message: 'TypeError: Cannot read property...',
stack: 'Error stack trace...',
filename: 'app.js',
lineno: 100,
colno: 25,
source: 'javascript',
level: 'error',
tags: {
component: 'UserProfile',
environment: 'production'
},
extra: {
userId: 'user_123',
action: 'button_click'
}
}
// 开启调试模式
webtracing.init({
debug: true, // 控制台输出详细日志
// ... 其他配置
})
// 手动检查SDK状态
console.log(webtracing.getState())
// 查看缓存队列
console.log(webtracing.getEventQueue())
// 强制发送缓存数据
webtracing.flush()
// 监控SDK自身状态
webtracing.onError((error) => {
console.error('WebTracing SDK Error:', error)
// 可以上报到其他监控系统
})
// 监控数据发送状态
webtracing.onSendSuccess((data) => {
console.log('数据发送成功:', data)
})
webtracing.onSendFailure((error, data) => {
console.error('数据发送失败:', error, data)
// 可以实现重试机制
})
WebTracing SDK 提供了完整的前端监控解决方案:
✅ 功能全面 - 涵盖行为、性能、错误、请求等8大监控领域
✅ 易于集成 - 支持原生JS、Vue2、Vue3多种使用方式
✅ 配置灵活 - 丰富的配置选项满足不同场景需求
✅ 性能优化 - 内置缓存机制和采样策略
✅ 数据可控 - 提供完整的生命周期钩子和过滤机制
通过 WebTracing SDK,您可以构建完整的前端监控体系,及时发现和解决问题,持续优化用户体验。
开始您的前端监控之旅!
提示:合理的监控策略不仅能帮助发现问题,更能为产品优化提供数据支撑。建议从核心功能开始,逐步完善监控体系。