乐趣区

关于前端:前端监控监控SDK手摸手Teach架构篇已开源

本文作者:cjinhuo,未经受权禁止转载。

概要

本文的次要目标是介绍一种可扩展性较好的 SDK 架构,让后续业务迭代的代码更清晰清朗。这种架构曾经在开源监控 SDK:mitojs 实际,有趣味的小伙伴能够去瞅瞅~

来到注释,本文分成三个局部

  • 背景
  • SDK 的架构与迭代
  • 结尾

背景

传统模式下,前端我的项目发到正式环境后就变成了一个黑盒子,所有报错信息只能通过用户应用时截图、口头形容发送到开发者,而后开发者来依据用户所形容的场景去模仿这个谬误的产生,这效率特低,所以很多开源或免费的前端监控平台就应运而生,比方:

  • sentry
  • webfunny
  • fundebug
  • 阿里云前端监控(ARMS)

等等一些优良的监控平台

自研的劣势

  1. 阿里云前端监控 (ARMS)fundebug须要投入大量金钱来作为反对,而 webfunnysentry虽是能够用 docker 私有化部署,但因为其源代码没有开源,二次开发受限
  2. 能够将公司所有的 SDK 对立成一个,包含但不限于:埋点平台 SDK、性能监控 SDK、录屏 SDK
  3. 能够无缝共享采集到的信息,比方错误信息能够和埋点信息联动,便可拿到更细的用户行为栈,更快的排查线上谬误
  4. 能够设计更好的服务端构造,雷同服务器的性能,不同的架构能够抗住不同的 QPS

监控平台的组成

SDK 的架构与迭代

前端监控的原理其实就那么几个,比方拦挡 http 申请就是重写原生函数:fetch、XMLHttpRequest,监控代码谬误:window.onerror,但 SDK 也是一个工程,是须要一直迭代追加性能的,所以良好的架构能够为前期迭代打下不错的地基

monorepo

借鉴了 sentryvue-next的代码目录构造,最终也是采纳 monorepo

它的劣势:

  1. 分模块打包、分模块热更新、分包公布(进步开发体验)
  2. 抽离抽象类、工具类到某个包,代码构造清晰(升高耦合性,进步代码可读性)

包与包之间的关系

多包打包与公布

试用了 lerna 后,发现它的性能太多,我想要的只是一个打包和公布的性能,最终是用 js 脚步编写依据命令行的入参来调用 rollupapinpmapi来打包和公布,具体打包脚本

可插拔的插件思路

该思路是从 rollup 和监控开源库 dora 中借鉴。

咱们须要监控:

  • xhr
  • fetch
  • hashroute
  • historyroute
  • error
    … 等等

传统模式

  1. 重写 xhr
  2. 在重写的过程中拿到想要的数据
  3. 通过公布订阅回传
  4. 在订阅核心中拿到数据,并解决

如果没有标准的束缚,每个重写的过程都会变的横七竖八,回传数据和解决数据可能到处都是。

如果咱们借鉴了插件模式后,会变成什么样呢?

插件模式

interface BasePluginType<T extends EventTypes = EventTypes, C extends BaseClientType = BaseClientType> {
  // 事件枚举
  name: T
  // 监控事件,并在该事件中用 notify 告诉订阅核心
  monitor: (this: C, notify: (eventName: T, data: any) => void) => void
  // 在 monitor 中触发数据并将数据传入以后函数,拿到数据做数据格式转换
  transform?: (this: C, collectedData: any) => any
  // 拿到转换后的数据进行 breadcrumb、report 等等操作
  consumer?: (this: C, transformedData: any) => void
}

这时就会有人说了,如果我的业务比这简单多了,那这个架构还能撑住吗?是能够的,将下面插件中的 3 个 hooks:monitor、transform、consumer分成更多 hooks,能够是 5 个也能够是 10 个,只有你分的颗粒度足够细,且齐全依照这些 hooks 的对应性能来编写代码,不论你的我的项目代码有多几十万行,你的代码层次结构都是很清晰的

举个🌰:监听 unhandlerejection 的插件

插件理论在代码中的应用

在 Vue3 应用 @mitojs/vue

// main.ts
import {createApp} from 'vue'
import App from './App.vue'
import {init} from "@mitojs/browser";
import {vuePlugin} from "@mitojs/vue";

const app = createApp(App)
const MitoInstance = init({
  vue: app,
  dsn: 'https://test.com/yourInterface',
  maxBreadcrumbs: 100
},[vuePlugin])

能够去 vue3 Demo 体验一下 sdk 收集的数据,更多信息能够拜访 vue3 接入指南

@mitojs/core

下面讲完插件是形成整个 SDK 的次要链路,当初讲下最根本的一些工具类,来串联这些插件,因为须要反对多个端,每个端须要监听的事件、上报形式、可配置项的是不同的,所以须要抽离多个抽象类,不便扩大。如下是 @mitojs/core 的整体思维导图

浏览器的整体思维导图

微信小程序的整体思维导图

可迭代性

后续如果有人想 pull request node 监控其余小程序的监控,只有依照这个插件模式开发,可迭代性便会大大提高

结尾

🤔 小结

该架构的思维可实用于任何 SDK,不同 SDK 中对应插件的个数和作用不同。总而言之,把一个大性能分隔成几个小性能区域,在指定的区域写指定性能的代码,让代码逻辑有法则可循。

下一篇「监控 SDK 手摸手 Teach- 实现篇」会讲具体在插件代码的编写,敬请期待~

🧐 开源

老仓库 monitor 的谬误监控原作者已不再保护,举荐到新的仓库 mitojs,新 SDK 重构后,包的体积更小、代码架构更清晰,耦合性更低,性能上齐全蕴含了老仓库,也推出了最新的 mitojs 文档,目前有局部人在用 mitojs 在做本人的监控平台或者埋点相干业务,如果你感兴趣能够,无妨过去瞅瞅 😘

📞 分割 & 内推

字节架构前端大量招人,内推可帮忙批改简历和实时查问面试进度,欢送砸简历到我的 邮箱:chenjinhuo@bytedance.com

如果你对字节架构前端、谬误监控、埋点感兴趣、也间接分割我的 微信:cjinhuo

Have A Good Day!!!

退出移动版