前端监控与错误追踪实战指南:构建稳定应用的终极方案

前端监控与错误追踪实战指南

在现代化的前端应用中,完善的监控和错误追踪系统是保障用户体验的关键。本文将深入探讨如何构建一套完整的前端监控体系,从错误捕获到性能分析,全方位守护你的应用。

一、错误捕获机制

1. 全局错误监听

javascript 复制代码
// 捕获全局错误
window.addEventListener('error', (event) => {
  const errorInfo = {
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    error: event.error?.stack,
    type: 'error',
    timestamp: Date.now()
  };
  
  // 发送到监控服务器
  sendToMonitoring(errorInfo);
});

// 捕获未处理的Promise rejection
window.addEventListener('unhandledrejection', (event) => {
  const errorInfo = {
    message: event.reason?.message || 'Unhandled Promise Rejection',
    stack: event.reason?.stack,
    type: 'unhandledrejection',
    timestamp: Date.now()
  };
  
  sendToMonitoring(errorInfo);
});

2. Vue应用中的错误处理

javascript 复制代码
// Vue 3 全局错误处理器
app.config.errorHandler = (err, vm, info) => {
  const errorInfo = {
    message: err.message,
    stack: err.stack,
    component: vm?.$options?.name,
    info: info,
    type: 'vue-error',
    timestamp: Date.now()
  };
  
  sendToMonitoring(errorInfo);
};

3. React应用中的错误边界

javascript 复制代码
class ErrorBoundary extends React.Component {
  componentDidCatch(error, errorInfo) {
    const errorData = {
      message: error.message,
      stack: error.stack,
      componentStack: errorInfo.componentStack,
      type: 'react-error',
      timestamp: Date.now()
    };
    
    sendToMonitoring(errorData);
  }
  
  render() {
    return this.props.children;
  }
}

二、性能监控

1. 核心性能指标

javascript 复制代码
// 页面加载性能
const performanceData = {
  // 页面加载时间
  pageLoadTime: performance.timing.loadEventEnd - performance.timing.navigationStart,
  
  // DOM解析时间
  domParseTime: performance.timing.domComplete - performance.timing.domLoading,
  
  // 资源加载时间
  resourceLoadTime: performance.timing.domContentLoadedEventEnd - performance.timing.domContentLoadedEventStart,
  
  // 首次内容绘制
  firstContentfulPaint: performance.getEntriesByType('paint')
    .find(entry => entry.name === 'first-contentful-paint')?.startTime,
  
  // 最大内容绘制
  largestContentfulPaint: performance.getEntriesByType('largest-contentful-paint')
    .pop()?.startTime
};

// 发送性能数据
sendToMonitoring({ type: 'performance', data: performanceData });

2. API请求监控

javascript 复制代码
// 拦截fetch请求
const originalFetch = window.fetch;
window.fetch = async (...args) => {
  const startTime = performance.now();
  const url = args[0];
  
  try {
    const response = await originalFetch(...args);
    const endTime = performance.now();
    
    // 记录成功的API请求
    sendToMonitoring({
      type: 'api-request',
      url: url,
      status: response.status,
      duration: endTime - startTime,
      success: true
    });
    
    return response;
  } catch (error) {
    const endTime = performance.now();
    
    // 记录失败的API请求
    sendToMonitoring({
      type: 'api-request',
      url: url,
      error: error.message,
      duration: endTime - startTime,
      success: false
    });
    
    throw error;
  }
};

三、用户行为追踪

1. 页面访问追踪

javascript 复制代码
// 页面访问记录
function trackPageView() {
  const pageInfo = {
    url: window.location.href,
    referrer: document.referrer,
    userAgent: navigator.userAgent,
    screenResolution: `${window.screen.width}x${window.screen.height}`,
    viewport: `${window.innerWidth}x${window.innerHeight}`,
    timestamp: Date.now()
  };
  
  sendToMonitoring({ type: 'page-view', data: pageInfo });
}

// 页面离开时记录停留时间
let pageStartTime = Date.now();
window.addEventListener('beforeunload', () => {
  const stayTime = Date.now() - pageStartTime;
  sendToMonitoring({
    type: 'page-stay-time',
    url: window.location.href,
    duration: stayTime
  });
});

2. 用户交互追踪

javascript 复制代码
// 追踪用户点击
document.addEventListener('click', (event) => {
  const target = event.target;
  const clickInfo = {
    element: target.tagName,
    id: target.id,
    className: target.className,
    text: target.textContent?.substring(0, 50),
    x: event.clientX,
    y: event.clientY,
    timestamp: Date.now()
  };
  
  sendToMonitoring({ type: 'user-click', data: clickInfo });
}, true);

// 追踪表单提交
document.addEventListener('submit', (event) => {
  const formInfo = {
    formId: event.target.id,
    formAction: event.target.action,
    timestamp: Date.now()
  };
  
  sendToMonitoring({ type: 'form-submit', data: formInfo });
});

四、监控数据上报

1. 数据上报策略

javascript 复制代码
class MonitoringReporter {
  constructor(config) {
    this.config = {
      endpoint: '/api/monitoring',
      batchSize: 10,
      flushInterval: 5000,
      ...config
    };
    this.queue = [];
    this.init();
  }
  
  init() {
    // 定时上报
    setInterval(() => this.flush(), this.config.flushInterval);
    
    // 页面关闭时上报
    window.addEventListener('beforeunload', () => this.flush());
  }
  
  report(data) {
    this.queue.push(data);
    
    if (this.queue.length >= this.config.batchSize) {
      this.flush();
    }
  }
  
  async flush() {
    if (this.queue.length === 0) return;
    
    const dataToSend = [...this.queue];
    this.queue = [];
    
    try {
      await navigator.sendBeacon(
        this.config.endpoint,
        JSON.stringify(dataToSend)
      );
    } catch (error) {
      // 失败时重新加入队列
      this.queue.unshift(...dataToSend);
    }
  }
}

// 使用示例
const reporter = new MonitoringReporter({
  endpoint: 'https://your-monitoring-api.com/collect',
  batchSize: 5,
  flushInterval: 3000
});

function sendToMonitoring(data) {
  reporter.report(data);
}

五、错误分析与告警

1. 错误聚合分析

javascript 复制代码
class ErrorAnalyzer {
  constructor() {
    this.errorPatterns = new Map();
  }
  
  analyze(error) {
    // 提取错误特征
    const pattern = this.extractPattern(error);
    
    // 统计错误频率
    if (!this.errorPatterns.has(pattern)) {
      this.errorPatterns.set(pattern, {
        count: 0,
        firstSeen: Date.now(),
        lastSeen: Date.now(),
        samples: []
      });
    }
    
    const errorData = this.errorPatterns.get(pattern);
    errorData.count++;
    errorData.lastSeen = Date.now();
    errorData.samples.push(error);
    
    // 只保留最近的5个样本
    if (errorData.samples.length > 5) {
      errorData.samples.shift();
    }
    
    // 检查是否需要告警
    this.checkAlert(errorData);
  }
  
  extractPattern(error) {
    // 提取错误的关键特征
    return error.message.split(':')[0] + '|' + error.type;
  }
  
  checkAlert(errorData) {
    // 错误频率过高时触发告警
    if (errorData.count > 10) {
      this.triggerAlert({
        type: 'high-frequency-error',
        pattern: errorData.pattern,
        count: errorData.count,
        samples: errorData.samples
      });
    }
  }
  
  triggerAlert(alert) {
    // 发送告警通知
    console.warn('Alert triggered:', alert);
    // 可以集成邮件、短信、钉钉等通知方式
  }
}

六、最佳实践建议

  1. 采样策略:对于高流量应用,采用采样策略减少监控数据量
  2. 隐私保护:避免收集敏感用户信息,对数据进行脱敏处理
  3. 性能影响:监控代码本身要轻量,避免影响应用性能
  4. 数据安全:使用HTTPS传输监控数据,确保数据安全
  5. 分级告警:根据错误严重程度设置不同的告警级别

总结

构建完善的前端监控体系需要从错误捕获、性能监控、用户行为追踪等多个维度入手。通过实时监控和及时告警,我们可以快速发现和解决问题,持续提升用户体验。记住,好的监控系统是应用稳定运行的重要保障。

在实际项目中,可以考虑使用成熟的监控方案如Sentry、LogRocket等,它们提供了更完善的功能和更好的用户体验。但了解底层原理对于定制化需求仍然非常重要。

相关推荐
streaker3031 小时前
多 IDE/Agent 环境下的 Skill 管理方案
前端·javascript·ai编程
Mintopia1 小时前
密集信息展示:表格与布局的取舍与实践指南
前端
牛奶1 小时前
从一行字到改变世界:HTTP这三十年都经历了什么?
前端·http·http3
OpenTiny社区2 小时前
以界面重构文字,GenUI 正式发布!
前端·vue.js·ai编程
yuki_uix2 小时前
深入理解 JavaScript 的 this:从困惑到掌握的完整指南
前端·javascript
小贤哥2 小时前
死磕这几道js手写题
前端·程序员
Lee川2 小时前
🌐 深入 Chrome 浏览器:从单线程到多进程架构的进化之路
前端·架构·前端框架
学以智用2 小时前
Vue 3 项目核心配置文件详解
前端·vue.js
工边页字2 小时前
AI 开发必懂:Context Window(上下文窗口)到底是什么?
前端·人工智能·后端