从零开始搭建高效前端监控体系的实战总结

IT人钰岩 框架 阅读 3,027
赞 52 收藏
二维码
手机扫码查看
反馈

又踩坑了,前端监控方案折腾半天

最近在做一个项目,需要加个前端监控来收集一些用户行为数据。一开始想着挺简单的,用个现成的库不就行了?结果真做起来才发现事情没那么简单。

从零开始搭建高效前端监控体系的实战总结

试了好几个库,发现都有问题

我先是试了下 Sentry,这个库名气很大,功能也多。但是配置起来有点麻烦,而且我们项目里的一些自定义事件没法很好地集成进去。折腾了半天,还是放弃了。

然后我又试了下 Bugsnag,这个库相对来说简单一点,但是也有点水土不服。主要问题是我们的项目里有一些特殊的数据结构,传给它的时候总是出错。后来发现文档里对这部分支持得也不好,只好作罢。

最后决定自己写一个简单的监控方案

既然现成的库都不太行,我就想干脆自己写一个算了。反正我们项目里的需求也不复杂,就记录一些基本的用户行为和错误信息。

首先,我写了个简单的错误捕获器,用来捕捉全局的 JavaScript 错误:

window.onerror = function (message, source, lineno, colno, error) {
  const errorInfo = {
    message,
    source,
    lineno,
    colno,
    stack: error ? error.stack : ''
  };
  sendErrorToServer(errorInfo);
  return true; // 阻止浏览器默认的错误处理
};

function sendErrorToServer(errorInfo) {
  fetch('https://jztheme.com/api/error', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(errorInfo)
  });
}

这里我踩了个坑,一开始忘了设置 window.onerror 的返回值,导致浏览器的默认错误处理机制还在运行,日志里出现了重复的错误信息。改完后这个问题解决了,但还是有一个小问题:有时候错误信息会丢失,不过无大碍。

用户行为监控也不难

接下来是用户行为监控,主要是记录用户的点击事件和页面跳转。我用了 addEventListener 来监听这些事件:

document.addEventListener('click', function (event) {
  const clickInfo = {
    target: event.target.tagName,
    id: event.target.id || '',
    class: event.target.className || '',
    text: event.target.textContent || '',
    timestamp: new Date().toISOString()
  };
  sendEventToServer(clickInfo);
});

window.addEventListener('hashchange', function () {
  const hashChangeInfo = {
    newHash: location.hash,
    oldHash: window.history.state?.oldHash || '',
    timestamp: new Date().toISOString()
  };
  sendEventToServer(hashChangeInfo);
});

function sendEventToServer(eventInfo) {
  fetch('https://jztheme.com/api/event', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(eventInfo)
  });
}

这里我注意到了一个问题,就是 hashchange 事件在某些情况下可能会被触发多次,导致日志里有很多重复的信息。后来试了下发现可以在 sendEventToServer 里加个去重逻辑:

let lastHash = '';
function sendEventToServer(eventInfo) {
  if (eventInfo.newHash !== lastHash) {
    fetch('https://jztheme.com/api/event', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(eventInfo)
    }).then(() => {
      lastHash = eventInfo.newHash;
    });
  }
}

这样就避免了重复发送相同的信息,虽然不是最优解,但简单有效。

总结一下

以上是我踩坑后的总结,希望能对你有帮助。其实前端监控并不难,关键是找到适合自己的方案。现成的库可能功能强大,但不一定适合每个项目。如果需求简单,自己动手写一个也不是什么难事。

如果你有更好的方案或者遇到过类似的问题,欢迎在评论区交流。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论