頂級開源專案 Sentry 20.x JS-SDK 設計藝術(概述篇)
阿新 • • 發佈:2021-03-10
![](https://img2020.cnblogs.com/blog/436453/202103/436453-20210310092527227-1821303548.png)
## SDK 開發
1. [頂級開源專案 Sentry 20.x JS-SDK 設計藝術(理念與設計原則篇)](https://mp.weixin.qq.com/s/5h5_q6lmbqUy1x__R9C2WA)
2. [頂級開源專案 Sentry 20.x JS-SDK 設計藝術(開發基礎篇)](https://mp.weixin.qq.com/s/YpysOHQslu9kjOw0SQQ_Ng)
## 系列
1. [Snuba:Sentry 新的搜尋基礎設施(基於 ClickHouse 之上)](https://mp.weixin.qq.com/s/RKaBfEh8Dlgt_iuHt10OPg)
2. [Sentry 10 K8S 雲原生架構探索,Vue App 1 分鐘快速接入](https://mp.weixin.qq.com/s/Rwwz4MJytA7va8zE8A5Y0w)
3. [Sentry(v20.x)玩轉前/後端監控與事件日誌大資料分析,使用 Helm 部署到 K8S 叢集](https://mp.weixin.qq.com/s/5xYtkzNx31dLsCAhoMPGrQ)
4. [Sentry(v20.x) JavaScript SDK 三種安裝載入方式](https://mp.weixin.qq.com/s/EV9M3Ru5rK5atAjTl1D9PA)
5. [Sentry(v20.x) JavaScript SDK 配置詳解](https://mp.weixin.qq.com/s/dlaejrn1kWBPiUJSmrzwow)
6. [Sentry(v20.x) JavaScript SDK 手動捕獲事件基本用法](https://mp.weixin.qq.com/s/4b4ojLkKGM6QX0z4Jq8nNQ)
7. [Sentry(v20.x) JavaScript SDK Source Maps詳解](https://mp.weixin.qq.com/s/-FySq0YUf2lJY2DjOORcIg)
8. [Sentry(v20.x) JavaScript SDK 故障排除](https://mp.weixin.qq.com/s/BHyLOCI53EUoswUjm1-dXw)
9. [Sentry(v20.x) JavaScript SDK 1分鐘上手效能監控](https://mp.weixin.qq.com/s/Z3Dp1fyzAEc5c89vy3Bzmw)
10. [Sentry(v20.x) JavaScript SDK 效能監控之管理 Transactions](https://mp.weixin.qq.com/s/Si2GLgGKsCwErJjJKFvtQg)
11. [Sentry(v20.x) JavaScript SDK 效能監控之取樣 Transactions](https://mp.weixin.qq.com/s/GdOFEE2aKVM7d5mWM1zVZw)
12. [Sentry(v20.x) JavaScript SDK Enriching Events(豐富事件資訊)](https://mp.weixin.qq.com/s/scjuodVzpApe59MBRwZtpQ)
13. [Sentry(v20.x) JavaScript SDK Data Management(問題分組篇)](https://mp.weixin.qq.com/s/DW061Q5ISf5FTXCYsMy5Tg)
## 概述
下面是一個實現新的 `Sentry SDK` 的指南。它涵蓋了事件提交的協議,以及客戶端的典型外觀和行為準則。
### 編寫一個SDK
`SDK` 的核心是一組實用程式,用於捕獲有關應用程式中異常狀態的資料。給定此資料後,它將構建併發送 `JSON` 有效負載並將其傳送到 `Sentry` 伺服器。
預計可用於生產環境的 `SDK` 包括以下各項:
* DSN配置
* 優雅故障(例如 Sentry 伺服器不可達)
* 設定屬性(例如 `tags` 和 `extra data`)
* 支援 `Linux`,`Windows` 和 `OS X`(如果適用)
以下情況需要基於 Feature 的支援:
* 如果有 Cookie 資料可用,則預設情況下不會發送
* 如果有 POST 資料,則預設情況下不會發送
此外,強烈建議您使用以下功能:
* 自動錯誤捕獲(例如,未捕獲的異常處理程式 `uncaught exception`)
* 日誌框架整合
* 非阻塞事件提交
* 上下文資料助手(例如,設定當前使用者,記錄麵包屑)
* 事件取樣
* `Honor Sentry` 的 `HTTP 429 Retry-After` header
* 事件前和事件後傳送鉤子
* 堆疊跟蹤中的區域性變數值(在可能的平臺上)
* 為每個事件傳送一個 `environment`。如果使用者沒有檢測到或設定任何值,則應該使用 `production`。
請參閱 `features` 頁面,以獲取有關常見的 `Sentry SDK` 功能的描述。
### 終端使用者的用法
通常,對於終端使用者來說,使用 `SDK` 包括三個步驟,無論使用哪種語言,這三個步驟看起來幾乎是相同的:
1. SDK 的初始化(有時對使用者隱藏):
`JavaScript`
```js
Sentry.init({dsn: 'https://[email protected]/0'});
```
`Python`
```python
Sentry.init({dsn: 'https://[email protected]/0'});
```
2. 捕獲事件:
`JavaScript`
```js
var resultId = Sentry.captureException(myException);
```
`Python`
```python
result_id = sentry_sdk.capture_exception(my_exception);
```
3. 使用事件捕獲的結果:
`JavaScript`
```js
alert(`Your exception was recorded as ${resultId}`);
```
`Python`
```python
print('Your exception was recorded as %s', result_id);
```
理想情況下,`init` 允許多種配置方法。第一個引數應該總是 `DSN` 值(如果可能的話):
`JavaScript`
```js
Sentry.init({
'dsn': 'https://[email protected]/0',
'foo': 'bar'
})
```
**請注意:**
`SDK` 應接受一個空的 `DSN` 作為有效配置。
如果未初始化 `SDK`,或者使用空 `DSN` 初始化了 `SDK`,則 `SDK` 不應通過網路傳送任何資料,例如捕獲的異常。 根據平臺的不同,`SDK` 可能會避免執行不必要的初始化工作,並將其執行時佔用空間降至最低。
此外,你應該提供全域性函式來捕捉基本訊息或異常:
* `Sentry.captureMessage(message)`
* `Sentry.captureException(exception)`
### 解析DSN
鼓勵SDK通過建構函式允許任意選項,但必須允許第一個引數作為DSN字串。該字串包含以下位:
```
'{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}'
```
您將向其傳送請求的最終端點按照以下方式構造:
```
{BASE_URI} = '{PROTOCOL}://{HOST}{PATH}'
'{BASE_URI}/api/{PROJECT_ID}/{ENDPOINT}/'
```
`Sentry` 提供以下端點:
* `/envelope/` 用於使用 `Envelopes` 的任何提交。
* `/store/` 用於提交簡單的 `JSON` 事件。
* `/minidump/` 用於包含 `minidump` 的 `multipart` 請求。
* `/unreal/` 用於虛幻引擎4崩潰報告。
* `/security/` 用於瀏覽器 `CSP` 報告,通常在瀏覽器而不是 `SDK` 中進行配置。
有關如何組成適當的請求有效負載的資訊,請檢視相應的端點。
例如,給定以下建構函式:
```js
Sentry.init({dsn: 'https://[email protected]/1'})
```
您應該解析以下設定:
* URI = `https://sentry.example.com`
* Public Key = `public`
* Project ID = `1`
對於純 `JSON` 有效負載的最終 `POST` 請求隨後將傳輸到:
```
'https://sentry.example.com/api/1/store/'
```
**請注意:**
`DSN` 的 `secret` 部分是可選的,目前已被棄用。如果提供的 `Sentry` 的未來版本將完全忽略它,clients 仍然應該尊重它。 DSN 解析程式碼不得要求設定 `secret key`。
### 認證
預期將與訊息正文(`message body`)一起傳送身份驗證標頭(`authentication header`),該訊息標頭用作所有權識別符號(`ownership identifier`):
```
X-Sentry-Auth: Sentry sentry_version=7,
sentry_client=,
sentry_timestamp=,
sentry_key=,
sentry_secret=
```
僅當 `DSN` 中包含 `secret key` 部分時,才必須包含 `sentry_secret`。協議的未來版本將完全棄用 `secret key`。
**請注意:**
您應該在標頭的 `User-Agent` 部分中包含 `SDK` 版本字串,如果 `auth` 標頭中未傳送 `sentry_client` ,則將使用該字串。
在無法傳送自定義 `X-Sentry-Auth` 標頭的情況下,可以通過查詢字串傳送以下值:
```
?sentry_version=7&sentry_key=&sentry_secret=...
```
`sentry_key`
* 必需的。`public key` 應作為 `SDK` 配置的一部分提供。
`sentry_version`
* 必需的。協議版本。該協議的當前版本為 `7`。
`sentry_client`
* 標識 `SDK`(包括其版本)的任意字串。典型的模式是 `client_name/client_version`。
例如,`Python SDK` 可能會將其作為 `raven-python/1.0` 傳送。
`sentry_timestamp`
* `Unix` 時間戳,表示生成此事件的時間。
`sentry_secret`
* 應該作為 `SDK` 配置的一部分提供的金鑰。
該 `key` 已被有效棄用,但由於某些較早的 `Sentry` 版本在大多數情況下都需要它,因此 `SDK` 仍應暫時釋放該 `key`。該 `secret key` 將在Sentry的未來版本中完全淘汰。
### HTTP Headers
我們建議始終傳送以下標頭:
* `content-type`
* `content-length`
根據 `CORS` 的策略,允許以下附加頭:
* `x-sentry-auth`
* `x-requested-with`
* `x-forwarded-for`
* `origin`
* `referer`
* `accept`
* `authentication`
* `authorization`
* `content-encoding`
* `transfer-encoding`
### 請求壓縮
強烈建議 `SDK` 在將請求正文傳送到伺服器之前先對其進行壓縮,以保持資料量較小。首選方法是傳送 `content-encoding` 標頭。 `Relay` 和 `Sentry` 接受以下內容編碼:
* `gzip`:使用 [LZ77](http://en.wikipedia.org/wiki/LZ77_and_LZ78#LZ77) 壓縮演算法。
* `deflate`:使用 [zlib](http://tools.ietf.org/html/rfc1950) 結構與 [deflate](https://tools.ietf.org/html/rfc1951) 壓縮演算法。
* `br`:使用 [Brotli](https://en.wikipedia.org/wiki/Brotli) 演算法。
### 傳輸編碼
建議僅對非常大的請求使用傳輸編碼(`Transfer Encoding`)。 將標頭設定為 `transfer-encoding: chunked`,這可以省略 `content-length` 標頭,並要求將請求主體包裝到 `chunk` 標頭中。
有關更多詳細資訊,請參見 [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding)。
### 讀取響應
成功後,您將從伺服器收到一個 `HTTP` 響應,其中包含 `JSON` 有效負載以及有關已提交有效負載的資訊:
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "fc6d8c0c43fc4630ad850ee518f1b9d0"
}
```
請注意 `Sentry` 將使用的響應程式碼。始終檢查 `200` 響應,這將確認訊息已交付。一個小級別的驗證會立即發生,這可能會導致不同的響應程式碼(和訊息)。
### 處理錯誤
我們強烈建議您的 `SDK` 妥善處理來自 `Sentry` 伺服器的故障。 具體來說,`SDK` 必須遵守 `429` 狀態程式碼,並且在 `Retry-After` 之前不要嘗試傳送。如果 `Sentry` 不可用,則 `SDK` 應該丟棄事件,而不是重試。
要在開發過程中除錯錯誤,請檢查響應標頭和響應正文。 例如,您可能會收到類似於以下內容的響應:
```http
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Sentry-Error: failed to read request body
{
"detail":"failed to read request body",
"causes":[
"failed to decode zlib payload",
"corrupt deflate stream"
]
}
```
`X-Sentry-Error` 標頭和響應正文並不總是包含一條訊息,但是它們仍然可以幫助除錯客戶端。發出時,它們將包含精確的錯誤訊息,這對於識別根本原因很有用。
**請注意:**
我們不建議即使錯誤響應標頭中聲明瞭 `Retry-After`,`SDK` 也不會在發生錯誤時自動重試事件提交。如果請求一次失敗,則很有可能在下一次嘗試時再次失敗。重試次數過多可能會導致進一步的速率限制或 `Sentry` 伺服器的阻塞。
### 併發(作用域 Scope 和集線器 Hub)
`SDK` 應該通過 `hubs` 和 `scopes` 的概念來提供標準化的併發處理。統一 API 文件的“併發性”一章中對此進行了更詳細的說明。
### 整合層
`SDK` 在可能的情況下應該在較低的層次上整合,這樣可以捕獲儘可能多的執行時。這意味著,如果 `SDK` 可以直接掛鉤執行時或框架,這比要求使用者子類化特定基類(或混合使用 `helper`)更可取。例如,`Python SDK` 將在框架中對核心功能進行 `monkey` 補丁,以自動拾取錯誤並整合作用域處理。
```sh
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~