前言javascript
前端項目目前發現錯誤的方法有哪些呢?html
爲了解決目前項目開發和管理流程中:上線前case很難測全、上線後問題復現困難,而且溝通成本高的現狀,個人項目接入了sentry。前端
sentry,中文翻譯是哨兵。它是一個錯誤監控和收集工具。用戶在項目使用中,遇到報錯,sentry會第一時間通知開發者,項目出現了什麼錯誤,錯誤出如今哪兒,而且會幫咱們記錄錯誤。vue
使用sentry須要結合兩個部分,客戶端與服務端。客戶端就是你須要去監聽的項目。而服務端就是一個數據管理平臺,它會展現已收集到的錯誤信息和項目信息。並支持項目管理,組員管理、郵件報警等功能。java
服務端平臺能夠本身搭建,也能夠直接使用sentry官方平臺。webpack
另外,sentry很是強大之處在於支持多種語言和框架 (docs.sentry.io/platforms/ ) 這裏我只研究了一下前端如何使用。其餘語言和框架、以及服務端的搭建暫時不涉及。web
咱們已經知道了sentry是什麼,那麼sentry到底怎麼用呢?ajax
首先,新建項目在sentry服務端平臺完成。sentry.io/。 新建完項目後,就會生成一個DSN串。 DSN是連接咱們要上報的項目和sentry服務端的鑰匙。每當咱們在sentry服務端建立一個新的項目,都會獲得一個獨一無二的DSN。在項目初始化時須要配置DSN到項目.這樣客戶端報錯,服務端就能抓到對應項目的錯誤了。npm
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高級用法。
try {
aFunctionThatMightFail();
} catch (error) {
// 上報error對象
Sentry.captureException(error);
}
// 上報文本信息
Sentry.captureMessage('Something went wrong');
複製代碼
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信息等
Sentry強於其餘錯誤監控平臺的特色之一就是支持sourcemap。只要咱們將sourcemap文件也上傳到服務器,就能夠在sentry平臺看到源代碼,從而快速定位錯誤。
前面提到須要將souceMap文件上傳到服務器,可是這樣子會將咱們的源碼文件暴露在客戶端,很是不安全。另外sentry解析須要從另一臺的服務器獲取sourcemap文件,也增長了服務器之間的開銷。
因此,官方推薦將sourcemap上傳到sentry服務器上。
將sourcemap上傳到sentry服務器的方式有3種。
第一種是使用sentry提供的webpack插件在項目打包時自動上傳。這種方式只須要在webpack打包配置中加入相關配置信息便可,是三種方式中最方便的方式。因此在業界大多使用這個方式。
第二種是使用sentry提供的上傳腳本,sentry-cli上傳。
第三種是直接直接調用sentry API 上傳,這種配置參數較多,比較麻煩。
綜合對比上面3種上傳方式,我堅決果斷的選擇了第一種,上傳後,錯誤能定位到源碼,看似很是順利。
可是使用沒多久,就發現一個問題,咱們的項目上線變慢了。
原來,sentry提供的上傳sourcemap的方法都是同步上傳,會致使上線變慢。 因此,咱們能夠將其優化爲異步上傳方式。
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是一個開箱即用、兼容性較好、功能強悍、而且生態圈很是完善的監控工具。你值得擁有😏。