前端监控搭建踩坑

今年年初老板说要搞前端监控,我就开始折腾。现在上线几个月了,记录一下。

需求

我们要监控这些东西:

  1. JS 报错
  2. 接口异常
  3. 页面性能
  4. 用户行为(可选)

方案选择

几个主流方案:

  1. Sentry:功能全,但收费,自建部署复杂
  2. 自研:灵活,但工作量大
  3. 阿里云 ARMS:国内访问快,但有点贵

最后选了 Sentry 自建版本,主要是团队有运维资源。

采集端

错误采集

// 全局错误
window.onerror = function(message, source, lineno, colno, error) {
  reportError({
    type: 'js_error',
    message,
    stack: error?.stack,
    url: window.location.href,
  });
};

// Promise unhandledrejection
window.addEventListener('unhandledrejection', (event) => {
  reportError({
    type: 'promise_error',
    message: event.reason,
  });
});

有个坑:压缩后的代码报错,行号对不上。需要上传 source map 到 Sentry。

性能采集

const timing = performance.getEntriesByType('navigation')[0];
const paint = performance.getEntriesByType('paint');

const metrics = {
  // 首次渲染
  FP: paint.find(e => e.name === 'first-paint')?.startTime,
  // 首次内容渲染
  FCP: paint.find(e => e.name === 'first-contentful-paint')?.startTime,
  // DOM 加载完成
  DCL: timing.domContentLoadedEventEnd - timing.domContentLoadedEventStart,
  // 页面完全加载
  Load: timing.loadEventEnd - timing.loadEventStart,
};

现在新的 API 是 PerformanceObserver,支持更多指标:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === 'largest-contentful-paint') {
      console.log('LCP:', entry.startTime);
    }
  }
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });

Source Map 问题

这是最大的坑。

生产环境代码是压缩过的,报错信息基本没用。需要上传 source map 到监控平台。

我们用 webpack 插件:

const { SentryWebpackPlugin } = require('@sentry/webpack-plugin');

module.exports = {
  plugins: [
    new SentryWebpackPlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: 'my-org',
      project: 'my-project',
      include: './dist',
    }),
  ],
};

注意:source map 不要部署到生产服务器!会暴露源代码。只在构建时上传到 Sentry,然后删掉。

告警配置

一开始我给所有错误都配了告警,结果手机响个不停。后来改成:

  1. 错误率超过阈值告警
  2. 同一错误超过 N 次告警
  3. 新出现的错误类型告警

还要配置静默时段,不然半夜被叫起来看日志很痛苦。

收获

上线几个月,发现了几个之前没注意到的 Bug:

  1. 某个旧版 Safari 的兼容问题
  2. 一个接口偶发性超时
  3. 第三方脚本加载失败导致页面卡死

这些东西光靠测试是测不出来的,线上监控确实有必要。

建议

  1. 先想清楚要监控什么,别上来就全量采集
  2. 告警要克制,太多了会麻木
  3. 有监控只是第一步,更重要的是跟进处理

我们现在每周看一次监控报告,整理出需要修复的问题,逐步迭代。