Sentry是一套用於捕獲產品錯誤的開源項目,其下支持不少語言、框架。javascript
這裏就只闡述在前端JavaScript方向的處理操做css
在咱們公司以前的應用場景裏,不少項目都是使用kibana
來作信息統計。可是咱們沒法清楚的知道應用的運行狀態是怎麼樣的。當某個客戶在使用咱們開發產品時,若是報錯、崩潰。用戶只能向客服尋求幫助,再交接給咱們的開發人員進行復現、修復。其中由於不清楚具體的數據,開發人員是在復現時會很是的耗時。前端
而Sentry
的用途就是解決這一痛點問題,讓開發人員快速準確的定位到問題的根源所在,以達到快速修復,讓開發人員更注重於開發新的功能上面。減小時間資源上的浪費。java
由於Sentry
使用的是一種Hook
錯誤函數的技術,來達到捕獲錯誤的目的,因此咱們基本能夠無損耗的接入到現有的項目中去。react
下面是React
與Sentry
進行結合的一些基本步驟。webpack
React:git
#SentryBoundary.js
import { Component } from "react";
import Raven from "raven-js";
export default class SentryBoundary extends Component {
constructor(props) {
super(props);
this.state = { error: null };
}
componentDidCatch(error, errorInfo) {
this.setState({ error });
// 發送錯誤信息
Raven.captureException(error, { extra: errorInfo });
}
render() {
if (this.state.error) {
// 此處能夠寫成組件,當組件崩潰後,能夠替換崩潰的組件
console.log("React Error");
}
return this.props.children;
}
}
複製代碼
#index.js
Raven.config("DSN", {
release: release,
}).install();
ReactDOM.render(
<div>
<SentryBoundary>
<App />
</SentryBoundary>
</div>,
document.getElementById("root")
);
複製代碼
若是上面的代碼已經配置好後,那麼如今的應用是能夠捕獲到錯誤的,可是存在了一個問題,咱們目前的項目大多都使用webpack
進行打包,而打包後的代碼是混淆加密的代碼,沒法讓咱們準確的知道拋出錯誤的位置在哪裏。因此咱們須要上傳source-map
和混淆後的文件一塊兒上傳到Sentry
服務器上。方便咱們快速查找到問題所在的位置。github
這個上傳的配置及命令是比較繁瑣的。也是項目結合Sentry
的一個難點。web
上傳source-map
目前有兩種方式:windows
Sentry
提供的Webpack
插件進行配置,可是其靈活性不高。sentry-cli
的,其靈活性比較高,能夠針對不一樣項目進行單獨的配置。其配置較爲繁瑣,這裏就不在闡述。具體的React與Sentry結合的例子。可見我在github上的項目: react-sentry-demo。對每一個配置都有詳細的說明。其中的上傳source-map
,我使用的是第二種方法,並寫了一個腳本,實現了: 打包、環境檢測、認證檢測、上傳source-map、刪除本地source-map的操做,完成自動化,能夠把腳本直接遷移到現有的項目中去,改動也不會太大。
其核心上傳命令以下:
sentry-cli releases files v1.8 upload-sourcemaps {js文件和js.map所在目錄。若是沒有找到,sentry會遍歷其子目錄} --url-prefix '~/{過濾規則}'`;
複製代碼
在JavaScript中是有window.onerror
這個方法的,而Sentry
在前端的核心捕獲原理,就是經過重寫此方法,來對全部的錯誤進行捕獲。其實現的代碼大體以下:
let _winError = window.onerror;
window.onerror = function (message, url, lineNo, colNo, errorObj) {
console.log(` 錯誤信息: ${message} 錯誤文件地址: ${url} 錯誤行號: ${lineNo} 錯誤列號: ${colNo} 錯誤的詳細信息 ${errorObj}`);
}
複製代碼
而後Sentry
的工做就是獲取非錯誤的數據,如: user-agent
、瀏覽器信息
、系統信息
、自定義信息
等信息,而後交給Sentry
的生命週期函數,最後在把數據發送到Sentry
服務端,進行錯誤信息展現。
這裏所說的兼容性,其實也就是window.onerror
的兼容性
環境 | message | url | lineNo | colNo | errorObj |
---|---|---|---|---|---|
Firefox | ✓ | ✓ | ✓ | ✓ | ✓ |
Chrom | ✓ | ✓ | ✓ | ✓ | ✓ |
Edge | ✓ | ✓ | ✓ | ✓ | ✓ |
IE 11 | ✓ | ✓ | ✓ | ✓ | ✓ |
IE 10 | ✓ | ✓ | ✓ | ✓ | |
IE 9 | ✓ | ✓ | ✓ | ✓ | |
IE 8 | ✓ | ✓ | ✓ | ||
Safari 10 and up | ✓ | ✓ | ✓ | ✓ | ✓ |
Safari 9 | ✓ | ✓ | ✓ | ✓ | |
Opera 15+ | ✓ | ✓ | ✓ | ✓ | ✓ |
Android Browser 4.4 | ✓ | ✓ | ✓ | ✓ | |
Android Browser 4 - 4.3 | ✓ | ✓ | |||
微信webview(安卓) | ✓ | ✓ | ✓ | ✓ | |
微信webview(IOS) | ✓ | ✓ | ✓ | ✓ | ✓ |
WKWebview | ✓ | ✓ | ✓ | ✓ | ✓ |
UIWebview | ✓ | ✓ | ✓ | ✓ | ✓ |
標籤 | window.onerror是否能捕獲 |
---|---|
img | 能夠 |
script | 須要再script標籤添加crossorigin 屬性,並在服務端容許跨域。若是不使用這個屬性,錯誤信息只會顯示Script error. |
css | 不能 |
iframe | 不能 |
能夠發現其瀏覽器都支持此方法。只是有些運行環境不支持colNo
和errorObj
,可是這塊,Sentry
已經幫你處理好了,因此不用擔憂。只是會在展現錯誤的時候,信息不太完整而已。
從上面的淺入原理能夠看到,其核心捕獲是window.onerror
。那麼只要它能夠捕獲到的錯誤,都會發送到Sentry
上。
而window.onerror
能捕獲到的錯誤,除了Promise
,基本上能在控制檯出現的錯誤,都會捕獲到。也就是運行時的錯誤,包括語法錯誤。
關於捕獲Promise
錯誤的方案,能夠使用:
window.addEventListener('unhandledrejection', event => {})
來進行捕獲,可是此事件的兼容性不太好,目前只有webkit內核
支持這個事件。
以下代碼,是此方法所能捕獲到的:
const p = new Promise((reslove, reject) => reject('Error'))
p.then(data => {
console.log(data)
})
// Promise觸發了reject回調函數,可是卻沒有相應到catch來應對。從而致使報錯。
複製代碼
這裏的集成,也不是說捕獲Electron應用的錯誤,而是崩潰。由於Electron只是一個容器,裏面的內容仍是JavaScript應用。
剛剛也說到這裏的集成也只是去捕獲Electron崩潰的信息。而當Electron崩潰時,會觸發Electron的函數:crashReporter.start
,那麼咱們在這個函數裏去配置一下本身的sentry
信息:
import { crashReporter } from 'electron'
crashReporter.start({
productName: 'aoc-desktop',
companyName: 'alo7',
submitURL:
'https://sentry.com/api/34615/minidump/?sentry_key=3e05fe101f1f85008e853ff56908b7eb', // sentry提供的minidump接口
extra: {
// 額外信息
}
})
複製代碼
配置好後,能夠使用process.crash()
來模擬崩潰,以便查看Sentry是否能收到崩潰信息。
在上面的應用說的是上傳source-map
,可是這裏上傳的是Symbol。能夠把Symbol
理解爲另外一種source-map
。
Symbol的格式(後綴)有不少,Mac下是dSYM
,windows是pdb
。而在Sentry裏,暫時是不支持上傳pdb
的。須要使用dump_syms.exe
來把pdb
格式轉化成sym
格式。再上傳到Sentry裏。這樣就能夠在Sentry崩潰的時候,看到起崩潰的上下文了。以下圖:
這樣就能夠準確的定位到是哪裏出現了問題。
當Sentry服務端收到source-map
時,是經過你上傳時的url-prefix
信息,與source-map文件以及運行時的js文件,產生對應。流程圖以下:
我司(愛樂奇)招人,感興趣的小夥伴能夠來投簡歷呀。
彈性工做制、每日水果、同事都特別nice、96五、團建、五險一金...
地點上海浦軟大廈