前端监控学习总结

拓扑图

错误监控

1、js错误

try catch主动捕获,try catch不能捕获异步错误,会被全局onerror事件捕获

    try {
      const str = '11111'
      str.map()
    } catch (error) {
      errorCaptcher(error, error.message)
    }

window.onerror全局捕获,onerror绑定事件会被覆盖,需要使用自定义事件做下处理,不影响原有事件执行

// 全局事件捕获
export const errorTrackerReport = () => {
  // js错误
  const originError = window.onerror
  window.onerror = (msg, url, row, col, error) => {
    // 执行原有onerror事件
    originError && originError.call(window, msg, url, row, col, error)

    lazyReport('error', {
      message: msg,
      file: url,
      row,
      col,
      error: JSON.stringify(error, Object.getOwnPropertyNames(error), 2), // 直接传入error类型,序列化会丢失,
      errorType: 'jsError'
    })
  }
2、reject错误

promise未被catch捕获的reject,会被unhandledrejection捕获,添加全局监听捕获

  // promise未被捕获错误
  window.addEventListener('unhandledrejection', (error) => {
    lazyReport('error', {
      message: error.reason,
      error: JSON.stringify(error, Object.getOwnPropertyNames(error), 2), // 直接传入error类型,序列化会丢失,
      errorType: 'promiseError'
    })
  })
3、资源加载错误

资源加载错误需要使用window.addEventListener('error', () => {})捕获,需要筛选错误对象的标签,避免错误捕获重复上报。

  // ------- resource error --------
  window.addEventListener('error', (error) => {
    let target = error.target;
    let isElementTarget = target instanceof HTMLScriptElement || target instanceof HTMLLinkElement || target instanceof HTMLImageElement;
    if (!isElementTarget) {
      return; // js error不再处理
    }
    lazyReport('error', {
      message: "加载 " + target.tagName + " 资源错误",
      file: target.src,
      errorType: 'resourceError'
    });
  }, true)
4、语法错误

这个基本不要捕获,开发阶段eslint就可以抛出错误

5、框架错误

vue:Vue.config.handleError、errorCaptured
react: 错误边界
小程序:App.onError()、Page.onError()、wx.onError()

6、白屏

白屏的监控使用document.elementsFromPoint(x, y), 判断当前点返回的第一个元素是否为html、body等,判断是否为空白点位,判断多个点位是否为空白。

7、常见问题

window.onerror方式的错误监听,会覆盖原有onerror方法;使用自定义事件改写onerror;

js报错,会走进资源加载错误监听事件内,导致重复日志;判断错误标签是否为script、link、img、video、audio;

除了onerror可以精确到行、列信息,其他错误无法精确位置;其他错误捕获后,使用throw error,让window.onerror再捕获;

行为监控

1、手动埋点

这个没什么说的,sdk提供上报方法,外部直接调用

      <button
        style={{ 'marginRight': '20px' }}
        data-no="yes"
        onClick={() => actionTrackerReport('button', '手动埋点被点击了')}
      >

2、属性埋点

设置特定属性,全局监听click事件,触发上报功能。例如data-target="属性埋点被点击了"

export const autoActionTrackerReport = () => {
  window.addEventListener('click', (e) => {
    const clickedDom = e.target
    // 获取自动上报标识内容
    const target = clickedDom?.getAttribute('data-target')

    const no = clickedDom?.getAttribute('data-no')
    // 主动上报设置,避免重复
    if (no) return 

    if (target) {
      lazyReport('action', {
        actionType: 'click',
        data: target
      })
    } else {
      const path = getPath(clickedDom)
      lazyReport('action', {
        actionType: 'click',
        data: path
      })
    }
  })
}

3、自动埋点

代码同属性埋点,日志会记录点击的元素路径

4、常见问题

属性埋点和自动埋点监听click事件,依托于事件冒泡,容易被阻止;阻止冒泡的地方使用手动埋点;

开启自动埋点,触发手动埋点会冒泡到自动埋点,导致重复上报;添加特定属性,避免重复上报;

自动埋点,随便点击都会记录,怎么筛选掉无用的点击;TODO

PV

1、history路由

自定义事件改写history.pushState、history.replaceState

浏览器操作前进、后退;使用window.popstate

刷新页面:监听load事件

页面卸载:监听unload事件

2、hash路由

添加hashChange事件监听

自定义事件改写history.pushState,vue-router实现会优先使用history.pushState,不支持再使用location.hash改变

页面刷新,会被hashchange事件捕获

页面卸载:监听unload

UV

UV只需要登录后把用户信息,上传到接口即可

性能监控

1、web-vitals

使用三方库web-vitals,输出性能指标

const reportWebVitals = onPerfEntry => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};

2、performance

使用window.performance原生api计算

代码片段

      const {
        fetchStart,
        connectStart,
        connectEnd,
        requestStart,
        responseStart,
        responseEnd,
        domLoading,
        domInteractive,
        domContentLoadedEventStart,
        domContentLoadedEventEnd,
        loadEventStart,
      } = window.performance.timing;
      // 发送时间指标
      // 用户体验指标
      lazyReport('performance', {
        type: "timing", // 统计每个阶段的时间
        connectTime: connectEnd - connectStart, // TCP连接耗时
        ttfbTime: responseStart - requestStart, // 首字节到达时间
        responseTime: responseEnd - responseStart, // response响应耗时
        parseDOMTime: loadEventStart - domLoading, // DOM解析渲染的时间
        domContentLoadedTime:
          domContentLoadedEventEnd - domContentLoadedEventStart, // DOMContentLoaded事件回调耗时
        timeToInteractive: domInteractive - fetchStart, // 首次可交互时间
        loadTime: loadEventStart - fetchStart, // 完整的加载时间
      })

日志采集

采集方式

1、常规API

2、navigator.sendBeacon

3、JSONP方式,使用img标签

常见问题

异步xhr在页面卸载后,会被中止,导致丢失;

navigator.sendBeacon兼容性不太好;

上报太过频繁,服务器压力大;添加延迟并且合并上报;

error类型JSON.stringfy后会丢失;使用JSON.stringfy的第二个参数解决丢失问题;

TODO

日志上报接口开发

监控平台日志分析平台开发

demo代码

https://github.com/wufeng123456/front-monitor-sdk.git

参考链接

迄今为止最全的前端监控体系搭建篇(长文预警) - 知乎

  • 29
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值