
SDK 開發
系列
- Snuba:Sentry 新的搜索基礎設施(基於 ClickHouse 之上)
- Sentry 10 K8S 雲原生架構探索,Vue App 1 分鍾快速接入
- Sentry(v20.x)玩轉前/后端監控與事件日志大數據分析,使用 Helm 部署到 K8S 集群
- Sentry(v20.x) JavaScript SDK 三種安裝加載方式
- Sentry(v20.x) JavaScript SDK 配置詳解
- Sentry(v20.x) JavaScript SDK 手動捕獲事件基本用法
- Sentry(v20.x) JavaScript SDK Source Maps詳解
- Sentry(v20.x) JavaScript SDK 故障排除
- Sentry(v20.x) JavaScript SDK 1分鍾上手性能監控
- Sentry(v20.x) JavaScript SDK 性能監控之管理 Transactions
- Sentry(v20.x) JavaScript SDK 性能監控之采樣 Transactions
- Sentry(v20.x) JavaScript SDK Enriching Events(豐富事件信息)
- Sentry(v20.x) JavaScript SDK Data Management(問題分組篇)
概述
下面是一個實現新的 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-Afterheader- 事件前和事件后發送鈎子
- 堆棧跟蹤中的局部變量值(在可能的平台上)
- 為每個事件發送一個
environment。如果用戶沒有檢測到或設置任何值,則應該使用production。
請參閱 features 頁面,以獲取有關常見的 Sentry SDK 功能的描述。
最終用戶的用法
通常,對於最終用戶來說,使用 SDK 包括三個步驟,無論使用哪種語言,這三個步驟看起來幾乎是相同的:
- SDK 的初始化(有時對用戶隱藏):
JavaScript
Sentry.init({dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'});
Python
Sentry.init({dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'});
- 捕獲事件:
JavaScript
var resultId = Sentry.captureException(myException);
Python
result_id = sentry_sdk.capture_exception(my_exception);
- 使用事件捕獲的結果:
JavaScript
alert(`Your exception was recorded as ${resultId}`);
Python
print('Your exception was recorded as %s', result_id);
理想情況下,init 允許多種配置方法。第一個參數應該總是 DSN 值(如果可能的話):
JavaScript
Sentry.init({
'dsn': 'https://examplePublicKey@o0.ingest.sentry.io/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中進行配置。
有關如何組成適當的請求有效負載的信息,請查看相應的端點。
例如,給定以下構造函數:
Sentry.init({dsn: 'https://public@sentry.example.com/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=<client version, arbitrary>,
sentry_timestamp=<current timestamp>,
sentry_key=<public api key>,
sentry_secret=<secret api key>
僅當 DSN 中包含 secret key 部分時,才必須包含 sentry_secret。協議的未來版本將完全棄用 secret key。
請注意:
您應該在標頭的 User-Agent 部分中包含 SDK 版本字符串,如果 auth 標頭中未發送 sentry_client ,則將使用該字符串。
在無法發送自定義 X-Sentry-Auth 標頭的情況下,可以通過查詢字符串發送以下值:
?sentry_version=7&sentry_key=<public api key>&sentry_secret=<secret api key>...
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-typecontent-length
根據 CORS 的策略,允許以下附加頭:
x-sentry-authx-requested-withx-forwarded-fororiginrefereracceptauthenticationauthorizationcontent-encodingtransfer-encoding
請求壓縮
強烈建議 SDK 在將請求正文發送到服務器之前先對其進行壓縮,以保持數據量較小。首選方法是發送 content-encoding 標頭。 Relay 和 Sentry 接受以下內容編碼:
傳輸編碼
建議僅對非常大的請求使用傳輸編碼(Transfer Encoding)。 將標頭設置為 transfer-encoding: chunked,這可以省略 content-length 標頭,並要求將請求主體包裝到 chunk 標頭中。
有關更多詳細信息,請參見 MDN。
讀取響應
成功后,您將從服務器收到一個 HTTP 響應,其中包含 JSON 有效負載以及有關已提交有效負載的信息:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "fc6d8c0c43fc4630ad850ee518f1b9d0"
}
請注意 Sentry 將使用的響應代碼。始終檢查 200 響應,這將確認消息已交付。一個小級別的驗證會立即發生,這可能會導致不同的響應代碼(和消息)。
處理錯誤
我們強烈建議您的 SDK 妥善處理來自 Sentry 服務器的故障。 具體來說,SDK 必須遵守 429 狀態代碼,並且在 Retry-After 之前不要嘗試發送。如果 Sentry 不可用,則 SDK 應該丟棄事件,而不是重試。
要在開發過程中調試錯誤,請檢查響應標頭和響應正文。 例如,您可能會收到類似於以下內容的響應:
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 補丁,以自動拾取錯誤並集成作用域處理。
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)
