JavaScript集成Sentry

Sentry-JavaScript

Sentry是一套用於捕獲產品錯誤的開源項目,其下支持不少語言、框架。javascript

這裏就只闡述在前端JavaScript方向的處理操做css

在咱們公司以前的應用場景裏,不少項目都是使用kibana來作信息統計。可是咱們沒法清楚的知道應用的運行狀態是怎麼樣的。當某個客戶在使用咱們開發產品時,若是報錯、崩潰。用戶只能向客服尋求幫助,再交接給咱們的開發人員進行復現、修復。其中由於不清楚具體的數據,開發人員是在復現時會很是的耗時。前端

Sentry的用途就是解決這一痛點問題,讓開發人員快速準確的定位到問題的根源所在,以達到快速修復,讓開發人員更注重於開發新的功能上面。減小時間資源上的浪費。java

1. JavaScript

1.1. 接入

由於Sentry使用的是一種Hook錯誤函數的技術,來達到捕獲錯誤的目的,因此咱們基本能夠無損耗的接入到現有的項目中去。react

下面是ReactSentry進行結合的一些基本步驟。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")
);
複製代碼

1.1.1. 上傳source-map

若是上面的代碼已經配置好後,那麼如今的應用是能夠捕獲到錯誤的,可是存在了一個問題,咱們目前的項目大多都使用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 '~/{過濾規則}'`;
複製代碼

1.2. 淺入原理

在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服務端,進行錯誤信息展現。

1.2.1. 兼容性

這裏所說的兼容性,其實也就是window.onerror的兼容性

1.2.1.1. 運行環境兼容性

環境 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

1.2.1.2. 標籤兼容性

標籤 window.onerror是否能捕獲
img 能夠
script 須要再script標籤添加crossorigin屬性,並在服務端容許跨域。若是不使用這個屬性,錯誤信息只會顯示Script error.
css 不能
iframe 不能

能夠發現其瀏覽器都支持此方法。只是有些運行環境不支持colNoerrorObj,可是這塊,Sentry已經幫你處理好了,因此不用擔憂。只是會在展現錯誤的時候,信息不太完整而已。

1.3. 所能捕獲的信息

1.3.1. 錯誤信息

從上面的淺入原理能夠看到,其核心捕獲是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來應對。從而致使報錯。
複製代碼

1.3.2. 麪包屑信息

  • Ajax請求
  • URL地址的變化
  • UI點擊和按下的DOM事件
  • 控制檯的console信息
  • 以前的錯誤
  • 自定義的麪包屑信息

1.4. 展現信息

image

2. Electron集成

這裏的集成,也不是說捕獲Electron應用的錯誤,而是崩潰。由於Electron只是一個容器,裏面的內容仍是JavaScript應用。

2.1 接入

剛剛也說到這裏的集成也只是去捕獲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是否能收到崩潰信息。

2.1.1 上傳Symbol(符號表)

在上面的應用說的是上傳source-map,可是這裏上傳的是Symbol。能夠把Symbol理解爲另外一種source-map

Symbol的格式(後綴)有不少,Mac下是dSYM,windows是pdb。而在Sentry裏,暫時是不支持上傳pdb的。須要使用dump_syms.exe來把pdb格式轉化成sym格式。再上傳到Sentry裏。這樣就能夠在Sentry崩潰的時候,看到起崩潰的上下文了。以下圖:

這樣就能夠準確的定位到是哪裏出現了問題。

3. 淺入上傳檢索的原理

當Sentry服務端收到source-map時,是經過你上傳時的url-prefix信息,與source-map文件以及運行時的js文件,產生對應。流程圖以下:

其餘

我司(愛樂奇)招人,感興趣的小夥伴能夠來投簡歷呀。

彈性工做制、每日水果、同事都特別nice、96五、團建、五險一金...

地點上海浦軟大廈

相關文章
相關標籤/搜索