《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.im/post/5d5028d3f265da03c34bed9f 「暴脾气的乖乖女」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

前言

前端项目目前发现错误的方法有哪些呢?

  1. 测试同学测出来。 缺点:现在浏览器版本、手机机型太多,兼容性问题很难测完全。另外有些项目流程非常长和复杂,测试同学不能确保每次都能覆盖100%的Case;
  2. 同事code review。 缺点: 这个的缺点是时间成本高、而且大多时候,code review也只是发现代码风格问题,对于逻辑和业务,其他同学没有时间深入去读的;
  3. 上线线后用户投诉反馈。 缺点:用户的机型、浏览器百花齐放,我们复现问题很困难。另外大多用户不懂专业术语,表达问题不准确,沟通成本很高,这些都导致解决问题效率非常低下。

为了解决目前项目开发和管理流程中:上线前case很难测全、上线后问题复现困难,并且沟通成本高的现状,我的项目接入了sentry。

Sentry是什么?

​ sentry,中文翻译是哨兵。它是一个错误监控和收集工具。用户在项目使用中,遇到报错,sentry会第一时间通知开发者,项目出现了什么错误,错误出现在哪儿,并且会帮我们记录错误。

​ 使用sentry需要结合两个部分,客户端与服务端。客户端就是你需要去监听的项目。而服务端就是一个数据管理平台,它会展示已收集到的错误信息和项目信息。并支持项目管理,组员管理、邮件报警等功能。

​ 服务端平台可以自己搭建,也可以直接使用sentry官方平台。

​ 另外,sentry非常强大之处在于支持多种语言和框架 (docs.sentry.io/platforms/ ) 这里我只研究了一下前端如何使用。其他语言和框架、以及服务端的搭建暂时不涉及。

​ 我们已经知道了sentry是什么,那么sentry到底怎么用呢?

Sentry的接入

新建项目

​ 首先,新建项目在sentry服务端平台完成。sentry.io/。 新建完项目后,就会生成一个DSN串。 DSN是链接我们要上报的项目和sentry服务端的钥匙。每当我们在sentry服务端创建一个新的项目,都会得到一个独一无二的DSN。在项目初始化时需要配置DSN到项目.这样客户端报错,服务端就能抓到对应项目的错误了。

安装SDK

SDK的安装和我们平时项目引用第三方包的方式完全一样。 有cdn引入和npm包注入两种方式,这两种引入方式配置也一样。

<script src="https://browser.sentry-cdn.com/5.6.1/bundle.min.js" integrity="sha384-pGTFmbQfua2KiaV2+ZLlfowPdd5VMT2xU4zCBcuJr7TVQozMO+I1FmPuVHY3u8KB" crossorigin="anonymous"></script>


npm install @sentry/browser

配置

// When using npm, import Sentry
import * as Sentry from '@sentry/browser';

Sentry.init({ dsn: 'https://e88fad1ac10a4d86ba291f17f54b653c@sentry.io/1509915' });

注意:如果是Vue项目,请不要在开发环境使用sentry。 因为Vue项目使用sentry时,需要配置@sentry/integrations。而@sentry/integrations是通过自定义Vue的errorHandler hook实现的,这将会停止激活Vue原始logError。 会导致Vue组件中的错误不被打印在控制台中。所以vue项目不要在开发环境使用sentry。

​ 这里我再补充一下,为什么Vue项目要配置sentry集成器? 这里说的sentry集成器是用于增强sentry Api的SDK。 VUE项目配置了它, 就可以捕获引发错误的组件名称和props状态。

​ 此外,Integrations.Vue有以下配置选项:

​ \1. Vue:可选的,如果你不传入,则window.Vue必须存在;

​ \2. attachProps:可选的,默认为true。如果将其设置为false,Sentry将禁止发送所有Vue组件的活动组件的名称和props状态 。

​ \3. logErrors:可选的,默认为false。如果设置为true,Sentry会调用原始Vue的logError功能。

import Vue from 'vue'
import * as Sentry from '@sentry/browser'
import * as Integrations from '@sentry/integrations'

Sentry.init({
release: VERSION,
dsn: 'https://e88fad1ac10a4d86ba291f17f54b653c@sentry.io/1509915',
integrations: [
new Integrations.Vue({
Vue,
attachProps: true // 是否上报组件的 props
})
]
})

高级用法

​ 前面我们已经知道了如何将sentry的接入到项目中,这个时候sentry就已经可以帮我们上报错误信息啦。 sentry会默认上报页面抛出的所有未被捕获的错误(包括window.error 和promise异常)。但是,sentry还为我们提供了一些更高级的功能。接下来,我们看一下sentry高级用法。

常用功能

  1. 主动捕获并上报错误。 主动上报的方式有两种: 一种是直接上报文本信息,参数为一个字符串; 另一种是上报错误对象,参数为一个error 对象或者类对象。

try {
aFunctionThatMightFail();
} catch (error) {
// 上报error对象
Sentry.captureException(error);
}
// 上报文本信息
Sentry.captureMessage('Something went wrong');

  1. 丰富BUG上下文数据。

​ Sentry提供的上下文信息有5个user 、 tags 、 level 、fingerprint 、 extra data。 我们可以通过在 scope 上面设置这些信息。有两种设置方式: 丰富BUG上下文数据其实就是添加自定义信息到上报事件。

​ Sentry提供给我们可自定义的上下文信息的有:user 、 tags 、 level 、fingerprint 、 extra data。

​ 这些信息我们可以通过在 scope 上面设置来定义。有两种设置方式:

​ 一种是sentry.configScope,它会设置信息到sentry全局作用域。使用这种方式设置的信息,会被后续所有的上报事件携带。

​ 另一种sentry.withScope,这种方式会设置一个临时信息到当前事件上。可以理解为一次性的信息设置。这种方式设置的数据,只在当前事件生效。当我们想为某个事件单独设置信息,而不想影响“全局”作用域时,就可以用它。

下面是添加上下文信息的具体方法:

// 设置用户信息:
scope.setUser({ “email”: “xx@xx.cn”})
// 给事件定义标签:
scope.setTags({ ‘api’, ‘api/ list / get’})
// 设置事件的严重性:
scope.setLevel(‘error’)
// 设置事件的分组规则:
scope.setFingerprint(['{{ default }}', url])
// 设置附加数据:
scope.setExtra(‘data’, { request: { a: 1, b: 2 })

​ 使用scope.setUser 可以设置用户的id 、 username 、 ip、email等信息。

​ 使用scope.setTags可以给事件定义不同的键/值对。事件上报后,我们在后台查找的时候,筛选条件选项会多出来一些选项,就是通过setTags来设置的这些键值对。

​ scope.setLevel是用来设置事件的严重性的。参数包括:fatal 、error 、 warning 、 info 、 debug 。( fatal : 是事故,error 代表错误,上报的事件默认都为error )

​ 使用scope.setFingerprint可以自定义事件的分组规则。Sentry拥有一套默认的分组策略。但是这个有时候并不能满足我们的需求。例如sentry会将所有的UnhandledRejection分组在一起,但事实上我们想要更加细致的分组,比如按接口URL来分组。这里就可以使用scope.setFingerprint([‘’, url])来设置。

​ Sentry.setExtra可以设置附加数据,例如记录ajax请求的参数,返回值,header信息等

  1. 上传SourceMap文件。

​ Sentry强于其他错误监控平台的特点之一就是支持sourcemap。只要我们将sourcemap文件也上传到服务器,就可以在sentry平台看到源代码,从而快速定位错误。

​ 前面提到需要将souceMap文件上传到服务器,但是这样子会将我们的源码文件暴露在客户端,非常不安全。另外sentry解析需要从另外一台的服务器获取sourcemap文件,也增加了服务器之间的开销。

​ 所以,官方推荐将sourcemap上传到sentry服务器上

​ 将sourcemap上传到sentry服务器的方式有3种。

​ 第一种是使用sentry提供的webpack插件在项目打包时自动上传。这种方式只需要在webpack打包配置中加入相关配置信息即可,是三种方式中最方便的方式。所以在业界大多使用这个方式。

​ 第二种是使用sentry提供的上传脚本,sentry-cli上传。

​ 第三种是直接直接调用sentry API 上传,这种配置参数较多,比较麻烦。

​ 综合对比上面3种上传方式,我毫不犹豫的选择了第一种,上传后,错误能定位到源码,看似非常顺利。

​ 但是使用没多久,就发现一个问题,我们的项目上线变慢了。

​ 原来,sentry提供的上传sourcemap的方法都是同步上传,会导致上线变慢。 所以,我们可以将其优化为异步上传方式。

其他

  1. 捕获用户对崩溃的反馈。
  2. 在beforeSend等hook中添加过滤事件和自定义逻辑。
  3. addBreadcrumb 添加一次行为记录等。

Sentry.init({
dsn: 'https://e88fad1ac10a4d86ba291f17f54b653c@sentry.io/1509915',
beforeSend(event, hint) {
// Check if it is an exception, and if so, show the report dialog
if (event.exception) {
Sentry.showReportDialog({ eventId: event.event_id });
}
return event;
}
});

​ 捕获用户反馈的的方法是在sentry的beforeSend hook里调用 showReportDialog方法。 这样子,当错误发生时,客户端就会弹出让用户填写错误信息的弹窗。

​ 另外sentry还加入面包屑的概念。sentry中的面包屑其实就是Sentry自动记录的一些日志和事件。例如浏览器URL的改变,ajax请求、之前的错误事件等。记录这些信息可以为当前错误提供上下文,重现导致错误发生的步骤,为我们复现和调试错误提供了关键信息。Sentry也提供了自定义添加面包屑和关闭面包屑的API。这个不太常用,我就不赘述了。

​ 今天主要先讲sentry的作用和使用方法,要讲的就是这些了。最后总结一下: Sentry是一个开箱即用、兼容性较好、功能强悍、并且生态圈非常完善的监控工具。你值得拥有😏。

文章目录
  1. 1. Sentry是什么?
  2. 2. Sentry的接入
    1. 2.1. 新建项目
    2. 2.2. 安装SDK
    3. 2.3. 配置
  3. 3. 高级用法
    1. 3.1. 常用功能
    2. 3.2. 其他