[前端工程化]前端异常监控方案 - sentry

前端项目的痛点

前端是一个跑在客户端的程序,一旦项目上了线,用户的行为是不会被前端工程师所感知的,线上出现了问题,需要用户反馈,工程师在本地复现后才能排查问题,而如何复现是一个最为耗时的问题,用户得告知工程师第一步是什么,第二步是什么.....;此外,问题没法复现也是一个开发者很难处理的问题。cdfcd174bc54d10119506c610e9e6712.png

前端监控的背景

d892dd074d2096f953284fb1562475a6.png
o4GXyh.png

在前端工程里有一个重要的理念:「数据驱动视图」;对于一个单体应用,也就是传统意义上的 B-S 软件系统来说,因为数据的来源都是自己的服务提供的,这些数据本身可以从服务层监控到,这种情况下即便不加从前端角度的监控也是无妨的,多查查还是能找到问题所在。

bdb19bd98389f0555fd683c8858d82db.png
o4Gqmc.png

对于一些复杂的前端来说,会把一个前端拆成好多个独立前端项目,来提高开发进度,比如qiankun 这些微前端框架;而对于一些已有的第三方项目,会采用 iframe 的方式来集成;如果不在客户端侧进行监控的话,越来越多的服务会导致在追踪线上问题上越发复杂。

ps, 有些前端工程师会把 复杂的前端 称之为 「大前端」,我认为这样叫不太严谨,大前端的 「大」 是体现 「终端」 上,而不是 「复杂」 上,如果用户一直是使用浏览器这样的方式操作软件,即便开发再复杂也是一个前端。

解决办法(sentry)

2021年的时候,我想对自己的博客的渲染引擎做一些监控,因为博客是用 wordpress 改的,本身是用 PHP 写的,意外发现了 「sentry」 这一神器,它不仅可以监控后端服务,也可以对前端服务做监控。

f1d9ef3be696ad32a911b39136a01151.png
o4GmXT.png

「sentry」 是开源的,是用 Python 写的, 对外提供 SaaS 服务,也支持 私有化部署 。

去年 sentry 上线了 session replays 的功能,即可以保存用户的行为,这一功能很强大,借助 「rrweb」 这套录制回放工具,可以轻松发现问题。

最近我才知道,rrweb 是国人团队运营维护的,创始人居然是 「Koala」 的儿子...

sentry 的接入

2be5f87f79e2b8d27c0f9e368ddbb441.png
o4Gt8K.png

采用官方提供的私有化部署方案,服务还是蛮多的,在数据库选择上看到它用的是 「postgresql」「clickhouse」 ,并未出现 「mysql」

上传 source-map

一般来说,开发者不会传 source-map 文件到生产环境上,因为这样相当于把源代码暴露在网络环境中,为了能在快速定位线上问题,需要将生成的 source-map 上传到 「异常监控平台」 上,这样的话只有内部人员才能看到线上问题出现在哪里。

本文使用的打包工具是 「vite」,配置如下:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
  build: {
    sourcemap: true,
  },
  plugins: [react(),sentryVitePlugin({
    debug:true,
    url:'http://localhost:9000',
    authToken:'1111',
    org:'sentry',
    project:'siroi-demo',
    sourcemaps:{
      ignore: ['node_modules'],
      deleteFilesAfterUpload:'./dist/**/*.map', // 上传后删除 sourcemap 文件
  }
  })],
})

注意一定要删除原来的 sourcemap 文件,否则还会上传到生成环境。

ps :这是个最简单的应用,正式项目要面对的问题还有很多,比如处理 source-map 文件的拆包,路径源匹配和映射等问题。

我们模拟一个点击请求事件,用户在点击按钮后,三秒后服务器返回 null 数据(-,- 还是用 「虚拟列表」 那个项目)。

import { useState } from 'react'
import './App.css'
// import VirtualList, { BaselineList } from './components/VirtualList'

function App() {
  const [count, setCount] = useState<Array<number> | null>([1,2,5,6,7]);

  const data = ((key)=>{
    const temp : Array<number> = [];
    for(let i =1 ;i <= key  ; i++){
      temp.push(i)
    }
    return temp;
  }
  )(100000)
  
  const errFunction = () => {
    setTimeout(()=>{
      setCount(null);
    }, 3000)
  }
  return (
    <>
      {/* <VirtualList data={data} HEIGHT={'500px'}/> */}
      {
        (count as unknown as Array<string>).slice(3,4).map((v , key) => <div key={key}>{v}</div>)
      }
     <div>{count?.[5]}</div>
     <button onClick={() => errFunction()}>哈哈</button>
      {/* <BaselineList data={data} HEIGHT={'500PX'}/> */}
    </>
  )
}
  
export default App

我们用 http-server 来启动一个服务,script 里配置如下

"serve": "cd ./dist && http-server"
b46fe6afdd53e4808917cafe1481c120.png
o4GNvP.png

浏览器打开 http://192.168.2.178:8080

ae544c8fe643ada64cb45bcf0107e1e3.gif
o4GQY6.gif

从控制台打开的异常报错也是经过 「混淆」 后的。

4cf07e166b04ecbc679ce26d49820acf.png
o4Gzen.png

之后打开 sentry,可以发现已经收到了一条报错异常

cedf0e7f15f32e9fe60aef98b4270861.png
o4G7TR.png

点开后可以直接看到异常问题的所在

5f50336b64bd5736fd52efe8eeacfe9d.png
o4GDKz.png

在会话重播中,也记录了这次异常发生的用户操作。

1b6ce594c378a51b24ecf21112905efb.gif
o4G6FA.gif

写在最后

时间是每一个参与敏捷开发的成员最宝贵的资源,维护线上产品的时间必须尽可能的少才能保证下次的软件交付,对于前端监控的需求也是越来越大。面对竞品公司,产品本身的性能也是开发者要关注的问题,而这些都需要监控。搜索资料的过程中发现字节的前端架构体系中的监控很大程度上借鉴了 sentry , 评论也有人质疑这是 kpi 产物🤣,除了监控体系,还有一个重量级的功能 - 「埋点」 ,下期再讲。

参考文章

  1. 字节前端监控实践 - 掘金 (juejin.cn)

  2. Source Map在前端监控中的应用和实践 - 掘金 (juejin.cn)

  3. 基于Sentry的前端性能监控平台搭建与应用 - 掘金 (juejin.cn)

  4. 不可忽视的前端监控 - 张鑫的文章 - 知乎 https://zhuanlan.zhihu.com/p/23310438

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值