Sentry是一個開源應用程序監控平臺,可幫助您實時識別問題。支持 web 先後端、移動應用以及遊戲,支持 Python、OC、Java、Go、Node、Django、RoR 等主流編程語言和框架 ,還提供了 GitHub、Slack、Trello 等常見開發工具的集成。javascript
本文主要討論的是Sentry在Docker環境下的搭建、Sentry SDK默認集成的功能以及在React應用程序中的使用。
html
1.一、Sentry搭建有兩種方式java
經過Python安裝node
經過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訪問;
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.一、將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;
},
});複製代碼
本文主要圍繞如何搭建和使用sentry,解決在線上環境中,由於應用跑在用戶瀏覽器中,發生錯誤時咱們若是要對其進行調試就會顯得比較困難。因爲本人水平和經驗有限,若有紕漏或建議,歡迎留言。若是以爲不錯,歡迎關注海致星圖,謝謝您的閱讀。