Sentry的搭建和使用

Sentry是一個開源應用程序監控平臺,可幫助您實時識別問題。支持 web 先後端、移動應用以及遊戲,支持 Python、OC、Java、Go、Node、Django、RoR 等主流編程語言和框架 ,還提供了 GitHub、Slack、Trello 等常見開發工具的集成。javascript

本文主要討論的是Sentry在Docker環境下的搭建、Sentry SDK默認集成的功能以及在React應用程序中的使用。
html

1.Sentry的搭建

1.一、Sentry搭建有兩種方式java

  1. 經過Python安裝node

  2. 經過Docker容器安裝webpack

這裏咱們經過Docker安裝(Docker的安裝教程較簡單,在這裏就不重複造輪子)git

1.二、安裝環境要求github

MIN_DOCKER_VERSION='1.10.0' 
docker -vMIN_COMPOSE_VERSION='1.17.0' 
docker-compose -vMIN_RAM=3072 # MB //你的內存至少3G複製代碼

1.三、搭建步驟web

今年7月份的時候Sentry官方更新了一版,將安裝的流程寫成了一個shell腳本(./install.sh),因此若是要使用全部默認設置,只需拉取onpremise(https://github.com/getsentry/onpremise)並運行./install.sh便可。docker

若是須要對包含的docker-compose.yml文件進行修改以知足您的需求或環境(例如添加GitHub憑據)。請在運行安裝腳本以前執行這些操做。
shell

自定義配置的推薦方法是按如下順序使用如下文件:

  • config.yml

  • sentry.conf.py

  • .env w /環境變量

如無心外, 一切正常, 端口默認是9000, 本地的話能夠直接打開localhost:9000訪問;

2.SDK默認集成的功能

  • Dedupe 自動過濾一些重複的事件

  • FunctionToString 使SDK可以上報詳細的錯誤函數信息

  • InboundFilters 便於開發者自行過濾或篩選所需的上報事件

  • Debug 該集成幫助方便的查看事件發送到Sentry服務器以前的實時信息,可選設置項:

    {
      debugger: boolean; // 在事件發送前觸發開發者工具debugger模式(若是打開了開發者工具)
      stringify: boolean; // 在事件發送前將事件序列化後經過console.log輸出
    }複製代碼
  • root: string; //root指定的路徑將被拼接到當前錯誤幀的basename以前(文件的完整路徑被分解爲[root, dir, basename, ext])
      iteratee: (frame) => frame); //該函數接收frame做爲參數處理後再返回
    }複製代碼

    RewriteFrames 該集成容許你對錯誤堆棧跟蹤的每一個幀進行處理

這裏重點講下瀏覽器端特有的集成功能:

  • Breadcrumbs 麪包屑 包含如下選項,默認所有集成

    beacon: boolean;  // 記錄使用Beacon API完成的HTTP請求
      console: boolean; // 捕捉console信息
      dom: boolean;     // 捕捉全部點擊以及鍵盤事件
      fetch: boolean;   // 記錄使用Fetch API完成的HTTP請求
      history: boolean; // 記錄history的變化
      sentry: boolean;  // 記錄主動上報的事件
      xhr: boolean;     // 記錄使用XMLHttpRequest API完成的HTTP請求
    }複製代碼
  • GlobalHandlers 全局設置是否須要對全部未捕獲錯誤或未處理的失敗響應進行處理

    {
      onerror: boolean;
      onunhandledrejection: boolean;
    }複製代碼
  • LinkedErrors 遞歸查詢錯誤堆棧的最深層次數和查詢字段

    {  
        key: string;  
        limit: number;
    }複製代碼
  • ReportingObserver,如下三類默認都包含

    {
      types: <'crash'|'deprecation'|'intervention'>[];
    }複製代碼
  • TryCatch 這個默認集成功能使用try/catch語句來包裹原生的定時及事件相關API來捕獲這些可能的異步錯誤

  • UserAgent 這個功能爲上報的信息附加了瀏覽器的user-agent,幫助咱們更好的瞭解和區分該用戶的使用環境


通常不建議修改或刪除這些集成,除非是有特別的需求或者衝突,修改方式爲

import * as Sentry from '@sentry/browser';

//刪除某集成
Sentry.init({
  dsn: 'https://<key>@sentry.io/<project>',
  integrations: integrations => {
    //刪除Breadcrumbs集成
    return integrations.filter(integration => integration.name !== 'Breadcrumbs');
  }
});
//修改某集成
Sentry.init({
  dsn: 'https://<key>@sentry.io/<project>',
  integrations: integrations => {
    //關閉Breadcrumbs集成自動收集console的功能
    return [...integrations, new Sentry.Integrations.Breadcrumbs({ console: false })];
  }
});複製代碼


3.在React中的應用

3.一、將Sentry集成到你的React應用

要將Sentry與React應用程序一塊兒使用,您須要使用@sentry/browser(Sentry的瀏覽器JavaScript SDK)

# Using yarn
$ yarn add @sentry/browser

# Using npm
$ npm install @sentry/browser複製代碼


在Sentry中完成項目設置後,Sentry將爲您提供一個咱們稱之爲DSN(Data Source Name)或數據源名稱的值。

import * as Sentry from '@sentry/browser';

//DSN由幾部分組成,包括協議,公鑰,服務器地址和項目標識符。
Sentry.init({dsn: "https://55b49309d120441bb162084e21e8ddbd@sentry.io/1521000"});複製代碼


@sentry/browser將報告從您的應用程序觸發的任何未捕獲的異常。你也能夠手動發送錯誤信息到sentry。

let errorVariable
try{
  console.log(errorVariable.slice(0,3))
}catch(e){
      //捕獲異常的錯誤 
      Sentry.captureException(e,{
      tags: {
          locale: 'en-us'
      }
  })
}複製代碼

運行代碼,毫無例外,sentry接送到了一個語法錯誤

細心的小夥伴可能發現了,項目通過打包以後代碼變得極其難閱讀,這樣的報錯信息對於咱們來講是不友好的。還好的是,Sentry supports un-minifying JavaScript via source maps

3.二、sourceMap

第一步,先安裝 @sentry/cli 工具

$ npm install -g @sentry/cli複製代碼

第二步,在項目根目錄下建立.sentryclirc文件

查詢組織的slug能夠訪問https://sentry.io/api/0/organizations/

查詢項目的slug能夠訪問https://sentry.io/api/0/organizations/{organization_slug}/projects/

//.sentryclirc
[defaults]
url=https://sentry.io/
org={organization_slug}
project={project_slug}複製代碼

若是是首次配置,咱們在須要webpack打包的文件目錄下運行sentry-cli login命令進行受權,命令行將會指引咱們打開瀏覽器新建一個authentication token,而後sentry-cli 自動將咱們填入的token寫入了咱們新建的.sentryclirc配置文件中

第三步,安裝@sentry/webpack-plugin

$ npm install -S @sentry/webpack-plugin複製代碼

第四步,webpack配置中引入Sentry Webpack Plugin插件,就能夠實如今webpack打包過程當中自動識別源文件和SourceMap文件並自動上傳。

//config-overrides.js
const {
  override,
  addWebpackPlugin
} = require("customize-cra")

const SentryCliPlugin = require('@sentry/webpack-plugin');

module.exports = override(
  addWebpackPlugin(new SentryCliPlugin({
    release: 'project20190804',
    include: 'build',
    urlPrefix: '~/',
    ignore: ['node_modules'],
  }))
)複製代碼

第五步,判斷文件是否上傳成功,能夠在sentry.io上查看

能夠看到文件已經上傳成功,其中~表明頁面的協議加域名,因此能夠檢查下具體文件是否是可以訪問的,避免SourceMap解析失敗。


通過了上面的一系列操做,讓咱們從新打包運行程序;果真沒讓baba失望!

順帶提一下,爲了不本地調試的時候也將錯誤上傳上去,咱們能夠經過Allowed Domains屬性進行配置

3.三、sentry的基本配置

Sentry.init({
  // Client's DSN. dsn: 'https://363a337c11a64611be4845ad6e24f3ac@sentry.io/297378', // An array of strings or regexps that'll be used to ignore specific errors based on their type/message
  ignoreErrors: [/PickleRick_\d\d/, 'RangeError'],
  // An array of strings or regexps that'll be used to ignore specific errors based on their origin url blacklistUrls: ['external-lib.js'], // An array of strings or regexps that'll be used to allow specific errors based on their origin url
  whitelistUrls: ['http://localhost:5000', 'https://browser.sentry-cdn'],
  // Debug mode with valuable initialization/lifecycle informations.
  debug: true,
  // Whether SDK should be enabled or not.
  enabled: true,
  // Custom integrations callback
  integrations(integrations) {
    return [new HappyIntegration(), ...integrations];
  },
  // A release identifier.
  release: '1537345109360',
  // An environment identifier.
  environment: 'staging',
  // Custom event transport that will be used to send things to Sentry
  transport: HappyTransport,
  // Method called for every captured event
  async beforeSend(event, hint) {
    // Because beforeSend and beforeBreadcrumb are async, user can fetch some data
    // return a promise, or whatever he wants
    // Our CustomError defined in errors.js has `someMethodAttachedToOurCustomError`
    // which can mimick something like a network request to grab more detailed error info or something.
    // hint is original exception that was triggered, so we check for our CustomError name
    if (hint.originalException.name === 'CustomError') {
      const serverData = await hint.originalException.someMethodAttachedToOurCustomError();
      event.extra = {
        ...event.extra,
        serverData,
      };
    }
    console.log(event);
    return event;
  },
  // Method called for every captured breadcrumb
  beforeBreadcrumb(breadcrumb, hint) {
    // We ignore our own logger and rest of the buttons just for presentation purposes
    if (breadcrumb.message.startsWith('Sentry Logger')) return null;
    if (breadcrumb.category !== 'ui.click' || hint.event.target.id !== 'breadcrumb-hint') return null;

    // If we have a `ui.click` type of breadcrumb, eg. clicking on a button we defined in index.html
    // We will extract a `data-label` attribute from it and use it as a part of the message
    if (breadcrumb.category === 'ui.click') {
      const label = hint.event.target.dataset.label;
      if (label) {
        breadcrumb.message = `User clicked on a button with label "${label}"`;
      }
    }
    console.log(breadcrumb);
    return breadcrumb;
  },
});複製代碼


4.結語

本文主要圍繞如何搭建和使用sentry,解決在線上環境中,由於應用跑在用戶瀏覽器中,發生錯誤時咱們若是要對其進行調試就會顯得比較困難。因爲本人水平和經驗有限,若有紕漏或建議,歡迎留言。若是以爲不錯,歡迎關注海致星圖,謝謝您的閱讀。

相關文章
相關標籤/搜索