作为一位前端开发者,你是否有过这样的困扰。某个用户反馈说,他的页面某个按钮点击不了,或者是根本打不开,但是你本地根本没法复现。因为,你不能通过不断调试的方法,来定位问题和修复问题,所以它非常难以解决。这时,你不妨先了解一下前端异常和性能监控,通过接入监控你可以较为轻松的找到线上问题线索。

接入前端监控系统,有两种方案,一种是接入外部监控系统,另外一种是自研。我们选择了自研,自研的优势是你可以根据你的需求来定制。但是,从头开始搭建一个大型的系统,并不是一个简单的事情。你需要站在产品角度,将前端工程师的需求翻译成功能,并且要站在架构师的角度来合理分工,解决高并发、实时性的难点,保障系统能够可靠性的运行。如果,你想要学习大型系统如何设计或者自己想搭建一个前端监控平台,我愿意把我的经验和你分享。

  1. 北斗监控之接入篇:自研前端监控的快速接入方法
  2. 北斗监控之 SDK 篇:重写函数获取更多有用的线上信息
  3. 北斗监控之架构篇:分层架构搞定大数据的难题
  4. 北斗监控之告警篇:实现可靠、实时、准确告警的方法

北斗监控之接入篇:自研前端监控的快速接入方法

我们来看一下一个最简单的监控 SDK 是什么样的。

window.onerror =  (msg, source, line, column, error) => {
    errorReport({ msg, source, line, column, stack: error.stack })
}

window.addEventListener('unhandledrejection', (event) => {
    errorReport({ msg: event.reason })
})

在前端应用中,我们通过 onerror 来监听 js 中普通错误,通过 unhandledRejection 来监听 Promise 错误。拿到错误信息后,再通过一个自定义的 errorReport 函数,把收集上来的错误上报到后端接口就行。

这样我们就完成了一个最简单的前端监控 SDK。实际上,我们一个后端接口,收集的肯定不止一个前端应用。因此我们需要项目 ID 来对前端应用进行区分。

常用的接入方式:推广成本高

以接入 Sentry 监控 SDK 为例。

第一步,你得需要在平台新建一个项目,拿到项目的 dsn,这个 dsn 本质是一个项目 ID。

第二步,你需要通过 script 或 npm 的方式,把 Sentry 的 SDK 引进来。

第三步,你需要初始化 Sentry。

import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn:"https://examplePublicKey@o0.ingest.sentry.io/0",
});

你的应用 publicKey 是 1,他的应用 publicKey 2,Sentry 就是通过 dsn 中的 publicKey 来区分不同前端应用上报的数据的。所以,任何接 Sentry SDK 的前端应用都加上一个 dsn 的项目 ID,才能接 Sentry 监控。

大家可能觉得在业务代码中加个项目 ID ,再上次线成本也不高啊。但是大家站在监控平台的角度出发,公司内部有上千个项目要去推动接入,这看起来一点点的成本乘以一千倍,也会变得非常高。

思路:上线平台向 Web 动态注入

我们想到的一个思路是,针对 Web 前端应用场景,由上线平台或客户端向前端应用直接注入监控 SDK,省去业务接入的步骤。这样 App 中所有页面不就都能够得到监控了吗?

自动注入的方案很好,但怎么区分不同的 Web 前端应用?大家也肯定想到了,是 url。我们可以在 errorReport 错误上报的参数中,统一添加 url 作为项目统计标识。

function errorReport(event) {

    // 用 URL 作为项目统计标识
    const report = { ...event, url: location.href }
  
    fetch('58.com/monitor/js', {
      body: JSON.stringify(report),
    })
}

以URL为维度统计,会引发三个问题

首先是,现在我们有 url为维度,也有项目ID为维度的统计,两种方式要兼容,怎么办呢?

  • 如果一个项目,只有一个 URL,那么项目ID和URL实际是等价的。
  • 如果一个项目,有两个或三个 URL 呢,怎么办?
  • 但如果一个项目的 url 是动态变化的呢,比如文章详情页,url 通常是根据文章 ID 动态生成的。怎么办呢?

方案:兼容多种统计维度

我们提出了一种兼容多种统计维度的方案。

第一种是,项目ID方案。业务先到监控平台申请项目ID,再到业务中手动填写项目ID的方案,这种方案适用于任意项目。

第二种是,固定 URL 方案。在前面提到的 Web 场景中,上线平台会帮我们自动注入监控 SDK,业务又只有一个固定的 URL,就无需入侵业务代码,业务方直接在平台填写 URL 即可把项目监控起来。

第三种是,动态 URL 改良的正则方案。正则方案容易造成错误匹配,比如业务就填了一个 58.com/* 就会把公司的所有 58 域名下的数据都统计到一个项目中。改良正则方案可以解决大部分错误匹配的问题。规则如下:

  1. URL N 个部分的 N,和匹配规则的 N 个部分的 N,要相等。
  2. 可以用 * 匹配 domain 和 path 中的任意部分
  3. *的数量 < N/2,也就是说一个 URL 有 6 部分,只能用 2 个 *。

image-20210416110902115

虽然兼容多种统计维度的接入方案,是以 Web 为基础进行思考的。但实际开发中,Web 动态注入方案,通过前端推动后端接入比较难,同时模板场景非常复杂,占比最多的老项目较多维护迭代少,整体看来推动成本高收益较小。而 RN 上线平台比较统一,也没有模板的困扰,方案上会比 Web 简单很多,因此该方案最终会先在 RN 先落地。

小结

本篇章对传统的以项目 ID 为维度的接入方式进行了思考,创新性地提出了一种无需入侵业务代码的接入方案,降低了业务方的接入成本,推广起来也会非常容易。该方案会先在 RN 场景下进行落地,业务只需在上线时勾选接入北斗监控,RN 打包平台会自动将北斗 RN SDK 注入到业务中,然后可以直接在监控平台看到 RN 项目的监控数据。


fitfish
1.6k 声望950 粉丝

前端第七年,写一个 RN 专栏。