接入sentry-讓你的錯誤別再裸奔

前言javascript

前端項目目前發現錯誤的方法有哪些呢?html

  1. 測試同窗測出來。 缺點:如今瀏覽器版本、手機機型太多,兼容性問題很難測徹底。另外有些項目流程很是長和複雜,測試同窗不能確保每次都能覆蓋100%的Case;
  2. 同事code review。 缺點: 這個的缺點是時間成本高、並且大多時候,code review也只是發現代碼風格問題,對於邏輯和業務,其餘同窗沒有時間深刻去讀的;
  3. 上線線後用戶投訴反饋。 缺點:用戶的機型、瀏覽器百花齊放,咱們復現問題很困難。另外大多用戶不懂專業術語,表達問題不許確,溝通成本很高,這些都致使解決問題效率很是低下。

        爲了解決目前項目開發和管理流程中:上線前case很難測全、上線後問題復現困難,而且溝通成本高的現狀,個人項目接入了sentry。前端

Sentry是什麼?

         sentry,中文翻譯是哨兵。它是一個錯誤監控和收集工具。用戶在項目使用中,遇到報錯,sentry會第一時間通知開發者,項目出現了什麼錯誤,錯誤出如今哪兒,而且會幫咱們記錄錯誤。vue

         使用sentry須要結合兩個部分,客戶端與服務端。客戶端就是你須要去監聽的項目。而服務端就是一個數據管理平臺,它會展現已收集到的錯誤信息和項目信息。並支持項目管理,組員管理、郵件報警等功能。java

         服務端平臺能夠本身搭建,也能夠直接使用sentry官方平臺。webpack

         另外,sentry很是強大之處在於支持多種語言和框架 (docs.sentry.io/platforms/ ) 這裏我只研究了一下前端如何使用。其餘語言和框架、以及服務端的搭建暫時不涉及。web

        咱們已經知道了sentry是什麼,那麼sentry到底怎麼用呢?ajax

Sentry的接入

新建項目

         首先,新建項目在sentry服務端平臺完成。sentry.io/。 新建完項目後,就會生成一個DSN串。 DSN是連接咱們要上報的項目和sentry服務端的鑰匙。每當咱們在sentry服務端建立一個新的項目,都會獲得一個獨一無二的DSN。在項目初始化時須要配置DSN到項目.這樣客戶端報錯,服務端就能抓到對應項目的錯誤了。npm

安裝SDK

SDK的安裝和咱們平時項目引用第三方包的方式徹底同樣。 有cdn引入和npm包注入兩種方式,這兩種引入方式配置也同樣。api

<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([‘{{ default }}’, 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是一個開箱即用、兼容性較好、功能強悍、而且生態圈很是完善的監控工具。你值得擁有😏。

相關文章
相關標籤/搜索