最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【得物技术】前端项目使用Sentry错误监控实践

    正文概述 掘金(得物技术)   2021-04-24   1146

    前言

    鉴于前端正在向多元化方向发展,场景愈加复杂,生产环境也经常会出现一些本地环境和测试环境无法复现的问题。而且,用户的具体行为和操作我们也不可预期,后端错误监控又只能监测到发起请求后的错误日志,那么错误发生时我们就只能靠用户反馈。但是这种反馈不是实时的,往往也只有截图或者文字描述,无法提供我们需要的其他关键信息,加上生产环境的静态资源文件一般都是经过混淆压缩,我们拿到的报错堆栈信息也没有太大含义。

    因此,前端项目更加需要一套成熟的错误监控系统,能够帮助我们实时的监控项目运行状态,提供丰富的详细的错误信息,甚至能够提供场景还原能力。让开发人员能够及时对报错进行跟进解决。

    本文着重讲解一下前端项目接入Sentry的步骤和规则设置以及其他Sentry后台使用。

    为何选择Sentry

    1. 市场已有的成熟的监控平台
    • Fundebug
    • Bugsnag
    • Badjs
    • Sentry
    1. Sentry的优势
    • 开源,有免费版
    • 可以部署自己的服务器,安全
    • 错误信息及告警机制完善
    • 简单易上手,开发成本低
    • 错误追踪及状态流转及时,方便
    • 丰富的SDK
    • 社区活跃

    综合对比,Sentry的这些优势既能及时抓取生产环境的前端报错发出通知,又能够提供丰富的错误信息及路径方便开发人员定位解决,满足了前端项目错误监控的基本需求;又是开源免费的,可以搭建自己的服务器,不用担心数据及敏感信息泄露等风险,同时支持各种开发语言及框架。所以,最终选择了Sentry做为得物前端平台的错误监控方案。

    简介

    Sentry是一项可帮助您实时监控和修复错误的服务。该服务器使用Python,但是它包含用于在任何应用程序中从任何语言发送事件的完整API。

    • 官网:sentry.io
    • 社区:forum.sentry.io

    概念

    • Event:事件。

    每次产生的日志记录,每个event有很多元信息,包括事件级别,项目信息,环境等。可通过点击具体事件对应的“JSON”数据进行查看

    • Issue:问题。

    相同的地方产生的一个异常称为一个Issue(是同一类问题的聚合)。假如在同一个位置发生了两次报错,那么会产生两个Event事件,但是只有一个Issue。

    • DSN:客户端(具体项目)密钥。

    DSN是一个url,包含相关密钥信息,客户端与服务端(sentry服务器)就是通过这个DSN进行通信,上报错误信息的。

    • Auth Token:授权令牌。

    授权令牌允许基于你的账户使用Sentry API,我们主要用到使用@sentry/cli进行上传sourceMap文件等操作时,sentry/cli会基于Auth Token进行调用相应API方法。

    • Org:组织名称。

    对应公司部署的sentry服务器上的组织名称。

    • Release:版本号。

    • Project:客户端名称。(接入sentry的具体项目名)

    • Tag:标签。

    部署

    • 安装Docker-Compose
    • 拉取Sentry仓库
    • 修改对应配置文件
    • 域名映射
    • 创建管理员密码和用户

    接入

    1. 创建项目

    • Sentry服务器上创建一个新的项目:ProjectName(项目名),选择Team。
    • 选择对应开发语言模板,这里选择Vue。

    【得物技术】前端项目使用Sentry错误监控实践

    2. 工程接入Sentry

    • 创建项目后,会弹出配置详细步骤文档,按照文档配置即可。

    【得物技术】前端项目使用Sentry错误监控实践

    • 安装依赖
    $ yarn add @sentry/browser -D
    $ yarn add @sentry/integrations -D
    
    • 入口文件处生成Sentry实例
    import Vue from 'vue'
    import * as Sentry from '@sentry/browser'
    import * as Integrations from '@sentry/integrations'
    Sentry.init({
        dsn: 'https://xxx.sentry域名/项目id',
        integrations: [new Integrations.Vue({Vue, attachProps: true})],
    })
    

    P.S. 这里的dsn为刚刚创建项目对应的客户端密钥,在项目->设置->客户端密钥(DSN)出查看。

    【得物技术】前端项目使用Sentry错误监控实践

    3. 上传SourceMap

    【得物技术】前端项目使用Sentry错误监控实践

    Sentry官方提供了两种上传sourceMap的方式:使用Sentry-cli命令行和webpack插件。由于命令行方式太过繁琐,且与前端工程化概念脱离。因此采用webpack插件方式进行上传sourceMap文件。

    • 安装webpack插件
    yarn add @sentry/webpack-plugin -D
    
    • 项目根目录下添加Sentry配置文件:.sentryclirc

    @sentry/cli上传sourcemap文件时会自动检查该配置文件下的信息,并使用

    [defaults]
    url=https://xxxxxx       //  - sentry服务器地址
    org=xxx                  //  - 组织名称
    project=projectname      //  - 项目名称
    [auth]
    token=xxx                //  - auth token
    

    【得物技术】前端项目使用Sentry错误监控实践

    P.S. 注意,这里申请的Auth Token要选择project:read和project:releases权限。

    【得物技术】前端项目使用Sentry错误监控实践

    • webpack配置文件添加插件
    const SentryCliPlugin = require('@sentry/webpack-plugin')
    const version = '' // 版本号
    config.devtool('source-map')
    config.plugin('SentryCliPlugin').use(SentryCliPlugin, [{
      release: version,
      // 打包后的代码目录 根据项目实际调整
      include: './dist',
      // url路径访问到的js资源前缀 根据项目实际调整 默认不用动
      // urlPrefix: "~/static/js/",
      ignore: ['node_modules'],
      setCommits: {
        // ==================== 需要改成对应项目的git地址=============
        repo: 'https://xxx.xx.xx',
        // ==================== 需要改成对应项目的git地址=============
        auto: true,
      },
    }]
    )
    

    这里有几个点需要注意:

    • 上传的SourceMap格式需要为"source-map"
    • 版本号version可以根据实际情况及公司编码规范进行设置,且需要在入口处也填写这个版本号(保持一致)
    • urlPrefix设置需要跟实际资源路径一致(后面会具体讲解)

    4. 上传到sentry后删除SourceMap

    • 使用clean-webpack-plugin插件
    config.plugins.push(
      new CleanWebpackPlugin({
        cleanAfterEveryBuildPatterns: ["./dist/js/*.js.map"]
      })
    )
    
    • 使用rimraf,在postbuild脚本中执行删除
    "postbuild:prod": "rimraf ./dist/js/*.js.map"
    
    • 在打包完成后上传文件到服务器时,排除map文件

    5. 区分环境

    • package.json脚本命令
    "build:test": "cross-env BUILD_ENV=test vue-cli-service build",
    "build:prod": "cross-env BUILD_ENV=production vue-cli-service build",
    
    • 入口文件生成实例处
    import Vue from 'vue'
    import * as Sentry from '@sentry/browser'
    import * as Integrations from '@sentry/integrations'
    const isProd = process.env.BUILD_ENV === 'production'
    isProd && Sentry.init({
        dsn: 'https://xxx.sentry域名/项目id',
        integrations: [new Integrations.Vue({Vue, attachProps: true})],
    })
    
    • webpack配置文件处
    const SentryCliPlugin = require('@sentry/webpack-plugin')
    const version = '' // 版本号
    const isProd = process.env.BUILD_ENV === 'production'
    config.when(isProd, config => {
      config.devtool('source-map')
      config.plugin('SentryCliPlugin').use(SentryCliPlugin, [
        {
          release: version,
          // 打包后的代码目录 根据项目实际调整
          include: './dist',
          // url路径访问到的js资源前缀 根据项目实际调整 默认不用动
          // urlPrefix: "~/static/js/",
          ignore: ['node_modules'],
          setCommits: {
            // ==================== 需要改成对应项目的git地址=============
            repo: 'https://xxx.xx.xx',
            // ==================== 需要改成对应项目的git地址=============
            auto: true,
          },
        },
      ])
    })
    
    • 最后,也可以选择性修改Sentry异常上报方法
    import * as Sentry from '@sentry/browser'
    const isProd = process.env.BUILD_ENV === 'production'
    function ResetCaptureout(Sentry: any) {
      if (isProd) return Sentry
      Sentry.captureException = function() {
        const args = Array.prototype.slice.call(arguments).join(' ')
        return console.log('%csentry:', 'color:red;', args)
      }
      Sentry.captureMessage = function() {
        const args = Array.prototype.slice.call(arguments).join(' ')
        return console.log('%csentry:', 'color:green;', args)
      }
      return Sentry
    }
    Sentry = ResetCaptureout(Sentry)
    

    6. 完成上述步骤,重新部署以后可以到Sentry服务器上进行验证

    • 查看是否生成对应版本:项目 -> 版本

    【得物技术】前端项目使用Sentry错误监控实践

    • 查看SourceMap文件是否上传成功:点击进入某一个版本 -> 工件(artifacts)

    【得物技术】前端项目使用Sentry错误监控实践

    7. 看到版本以及对应的工件上传成功就表示已经接入完成,这时再发生报错我们就能看到具体源码信息了。

    扩展

    • WebHook关联

    Sentry提供很多插件集成,除了邮件通知功能还可以接入飞书或者钉钉等其他企业办公软件进行有效快速的通知。

    • 路径:项目 -> 设置 -> Legacy Integrations -> 选择Webhook -> 打开开关 -> Configure plugin

    【得物技术】前端项目使用Sentry错误监控实践

    【得物技术】前端项目使用Sentry错误监控实践

    • GitLab仓库集成
    • 路径:Sentry -> 设置 -> 集成 -> GitLab -> Add

    【得物技术】前端项目使用Sentry错误监控实践

    • 点击Add Another以后会弹出详细操作说明
    • 安装完以后可以选择Group下面对应的仓库进行添加
    • Issue关联

    【得物技术】前端项目使用Sentry错误监控实践

    告警设置

    告警规则

    1. 设置路径

    Sentry -> 项目 -> 设置 -> 警报 -> 编辑/新增

    1. 可选项说明
    • An event is seen:当一个事件发生时
    • An issue is first seen:错误第一次出现
    • An issue changes state from resolved to unresolved:针对已修复问题复现场景
    • An issue changes state from ignored to unresolved:当xx条件下“忽略”的问题重新触发时进行提醒
    • An issue is seen more than xx times in xx time:对于一些已知的低级别,不影响使用的问题可以设置超过多少次以后再进行告警
    • An event's tags match xx equal to/does not equal xxx:根据事件标签值进行相应决策
    • An event's level is equal/does not equal xxx:选择事件级别(致命的/错误/警告/日志)

    【得物技术】前端项目使用Sentry错误监控实践

    1. 触发动作

    当产生的event符合告警规则时,触发的提醒动作。可以选Email或者其他集成。由于公司内部使用飞书作为日常办公IM,故这里设置为触发飞书WebHook。效果如下图:

    【得物技术】前端项目使用Sentry错误监控实践

    入站过滤器

    通过入站过滤器可以针对某些版本、某些IP地址用户或者针对指定版本浏览器原因造成的问题进行过滤处理。最重要的是我们可以通过入站过滤器进行自定义过滤规则对一些已知可忽视问题进行设置,比如针对一些请求超时、没有权限,登录态失效等非代码健壮性问题。

    1. 设置路径

    Sentry -> 项目 -> 设置 -> 入站过滤器

    1. 查看过滤错误情况

    【得物技术】前端项目使用Sentry错误监控实践

    【得物技术】前端项目使用Sentry错误监控实践

    Issue Owners

    通过Issue Owners选项我们可以在Issue发生时自动建立Issue与责任人关联关系,与此同时直接发送邮件或者飞书通知给对应负责的小伙伴。一共有两种设置方式,都是根据正则表达式进行匹配

    1. 路径(path):通过指定源文件所在目录及owners

    2. 页面路由(url):通过指定具体页面路由及owners

    【得物技术】前端项目使用Sentry错误监控实践

    错误解决方案

    • Resolve
      • 当前版本解决:发完版本以后,修改issue状态
      • 下个版本解决:issue发现后马上解决,代码跟随下个版本上线
      • 其他版本:一般不使用该选项
    • Ignore
      • 时间维度:xx时间之前忽略(可自定义时间)
      • 数量维度:再出现xx次之前忽略
      • 用户维度:再有xx个用户复现这个错误之前忽略

    原理

    前端错误类型

    • 即时运行错误:代码错误
    • 资源加载错误
    • 图片加载错误

    上报错误的方法

    • 利用网络请求进行上报
    • 利用图片方式上报

    Sentry实现原理

    1. Init初始化,配置release和项目dsn等信息,然后将sentry对象挂载到全局对象上。
    2. 重写window.onerror方法。

    当代码在运行时发生错误时,js会抛出一个Error对象,这个error对象可以通过window.onerror方法获取。Sentry利用TraceKit对window.onerror方法进行了重写,对不同的浏览器差异性进行了统一封装处理。

    1. 重写window.onunhandledrejection方法。

    因为window.onerror事件无法获取promise未处理的异常,这时需要通过利用window.onunhandledrejection方法进行捕获异常进行上报。在这个方法里根据接收到的错误对象类型进行不同方式的处理。

    1. 如果接收到的是一个ErrorEvent对象,那么直接取出它的error属性即可,这就是对应的error对象。
    2. 如果接收到的是一个DOMError或者DOMException,那么直接解析出name和message即可,因为这类错误通常是使用了已经废弃的DOMAPI导致的,并不会附带上错误堆栈信息。
    3. 如果接收到的是一个标准的错误对象,不做处理
    4. 如果接收到的是一个普通的JavaScript对象
    5. 使用Ajax上传

    当前端发生异常时,最终会调用Fetch请求上报到对应的Sentry服务器上,这里需要用到在初始化Sentry时传入的DSN。

    踩坑记录

    • urlPrefix

    站点域名:www.demo.com

    静态资源路径:

    www.demo.com/assets/js/1…

    www.demo.com/assets/js/1…

    那么这里:~ = www.demo.com

    urlPrefix选项应该配置为:~/assets/js/

    P.S. 默认为~/static/js/

    【得物技术】前端项目使用Sentry错误监控实践

    以上面这张图为例:

    Sentry拉取资源的时候路径为:域名/js/chunk-xxxx.js

    • sourceMap需要为“source-map”类型,否则无法还原错误。
    • DSN配置为HTTPS协议头,因此需要处理跨域问题。
    • sentry报错可以通过控制台Network选项进行查看。
    • 遇到问题多跑跑sentry社区,或者扒一下之前的issue记录,能解决80%的问题。

    总结

    前端项目业务场景日益复杂,经常会出现一些诡异的Bug,测试也很难覆盖到100%场景。某些小的代码问题很有可能造成一些意想不到的后果。与其等待用户发现问题反馈时背锅,不如通过监控系统及早发现,趁带来实际损失之前将其夭折。

    参考文献

    www.feishu.cn/hc/zh-CN/ar… zhuanlan.zhihu.com/p/75385179 juejin.cn/post/684490… zhuanlan.zhihu.com/p/75577689 zhuanlan.zhihu.com/p/89539449

    文|Evan

    关注得物技术,携手走向技术的云端


    起源地下载网 » 【得物技术】前端项目使用Sentry错误监控实践

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元