前端监控sdk 应用稳定性监控

前端监控

为什么要做前端监控?

  • 更快发现问题和解决问题
  • 做产品的决策依据
  • 为业务扩展提供了更多可能性

指标数据监控

  • 异常监控(稳定性):js异常 promise异常 资源加载异常 (script或者link标签资源异常)
初始化参数
  • 项目初始化
  • 初始化参数
  • 参数校验
稳定性监控
  • 对于js错误监控,一般js运行时错误 通过监听window.onerror捕获错误
  • 需要获取到的错误信息有:(从错误对象中提取信息)
      1. 当前页面url地址
      1. 用户的浏览器类型
      1. 错误类型
      1. 错误详情
      1. 错误的行列信息
      1. 错误的堆栈信息
      1. 选择器信息 (先定位到最后一个触发事件 通过target.path获取路径 有id优先取id,没有id取className没有className取tagName)
  • 通过事件对象上的是否存在error对象可以判断是js错误还是一些静态资源加载异常。
  • 对于promise监控,监控promise错误分为两种:
      1. 通过promise.reject异常拦截,通过监听unhandledrejection方法
      1. 通过promise对象catch方法拦截,通过监听rejectionhandled方法
  • 当Promise被reject且没有reject处理器的时候,会触发unhandledrejection事件
// unhandledrejection错误监控
if (listenPromiseError) {
    window.addEventListener(
      'unhandledrejection',
      function (e) {
        const errObj = {
          name: e.type,
          message: JSON.stringify(e.reason) || '',
          stack: JSON.stringify({
            info: 'promise.reject异常拦截',
          }),
        };
        sendErrorException(errObj, sendParams);
      },
      true
    );
	// rejectionhandled错误监控
    window.addEventListener(
      'rejectionhandled',
      (e) => {
        const errObj = {
          name: e.type,
          message: JSON.stringify(e.reason) || '',
          stack: JSON.stringify({
            info: 'promise对象catch数据拦截',
          }),
        };
        sendErrorException(errObj, sendParams);
      },
      true
    );
  }
  • 接口错误监控
    • 接口错误监控可以对请求方法做拦截,如xhr的open和send方法
    • 下面简单实现了一下对XMLHttpRequest的拦截过程
    • 然后再通过addEventListener来监听对应的触发事件如load, error,abort
export function injectXHR() {
    let XMLHttpRequest = window.XMLHttpRequest;
    let oldOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
          this.logData = {
              method, url, async, username, password
          }
        return oldOpen.apply(this, arguments);
    }
    let oldSend = XMLHttpRequest.prototype.send;
    let start;
    XMLHttpRequest.prototype.send = function (body) {
        if (this.logData) {
            start = Date.now();
            let handler = (type) => (event) => {
                let duration = Date.now() - start;
                let status = this.status;
                let statusText = this.statusText;
                tracker.send({//未捕获的promise错误
                    kind: 'stability',//稳定性指标
                    type: 'xhr',//xhr
                    eventType: type,//load error abort
                    pathname: this.logData.url,//接口的url地址
                    status: status + "-" + statusText,
                    duration: "" + duration,//接口耗时
                    response: this.response ? JSON.stringify(this.response) : "",
                    params: body || ''
                })
            }
            this.addEventListener('load', handler('load'), false);
            this.addEventListener('error', handler('error'), false);
            this.addEventListener('abort', handler('abort'), false);
        }
        oldSend.apply(this, arguments);
    };
  • 监控白屏
      1. 定义白屏时长
      • 是指浏览器从响应用户输入网址地址,到浏览器开始显示内容的时间。
      • 白屏时间 = 页面开始展示的时间点 - 开始请求的时间点
      • window.performance.timing.responseStart -window.performance.timing.navigationStart
      • 可以定义一个白屏时长 如果白屏时间大于这个时长就上报
      1. 使用webAPI 的 MutationObserver 属性监控根元素内的dom数量,如果没有dom则白屏
const targetNode = document.getElementById("container");
if (targetNode) {
  // 当观察到变动时执行的回调函数
  const callback = function (mutationsList) {
    console.log(mutationsList, "11111");
    for (let i = 0; i < mutationsList.length; i++) {
      let mutation = mutationsList[i];
      if (mutation.type === "childList" && targetNode?.children?.length === 0) {
        console.log("白屏");
        break;
      }
    }
  };
  const config = { childList: true };
  if (window.MutationObserver) {
    const observer = new MutationObserver(callback);
    observer.observe(targetNode, config); // 观察器的配置(需要观察什么变动)
  }
}
const childDiv = document.createElement("div");
targetNode.appendChild(childDiv);
    1. 对页面上的9个点分横纵进行判断是否有元素,如果18次判断全部都没有检索到元素,可以断定发生白屏现象
export function blankScreen() {
  const wrapperSelectors = ["body", "html", "#container", ".content"];
  let emptyPoints = 0;
  function isWrapper(element) {
    let selector = getSelector(element);
    if (wrapperSelectors.indexOf(selector) >= 0) {
      emptyPoints++;
    }
  }
  onload(function () {
    let xElements, yElements;
    debugger;
    for (let i = 1; i <= 9; i++) {
      xElements = document.elementsFromPoint(
        (window.innerWidth * i) / 10,
        window.innerHeight / 2
      );
      yElements = document.elementsFromPoint(
        window.innerWidth / 2,
        (window.innerHeight * i) / 10
      );
      isWrapper(xElements[0]);
      isWrapper(yElements[0]);
    }
    if (emptyPoints >= 0) {
      let centerElements = document.elementsFromPoint(
        window.innerWidth / 2,
        window.innerHeight / 2
      );
      tracker.send({
        kind: "stability",
        type: "blank",
        emptyPoints: "" + emptyPoints,
        screen: window.screen.width + "x" + window.screen.height,
        viewPoint: window.innerWidth + "x" + window.innerHeight,
        selector: getSelector(centerElements[0]),
      });
    }
  });
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值