Sentry(v20.12.1) K8S 雲原生架構探索,JavaScript Enriching Events(豐富事件資訊)
阿新 • • 發佈:2021-01-25
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141125999-660437262.png)
## 系列
1. [Sentry-Go SDK 中文實踐指南](https://mp.weixin.qq.com/s/MLqRSh7D0YZzCKfG5xvsZw)
2. [一起來刷 Sentry For Go 官方文件之 Enriching Events](https://mp.weixin.qq.com/s/0Ke1gozUyUVny4-7B2mw0w)
3. [Snuba:Sentry 新的搜尋基礎設施(基於 ClickHouse 之上)](https://mp.weixin.qq.com/s/RKaBfEh8Dlgt_iuHt10OPg)
4. [Sentry 10 K8S 雲原生架構探索,Vue App 1 分鐘快速接入](https://mp.weixin.qq.com/s/Rwwz4MJytA7va8zE8A5Y0w)
5. [Sentry(v20.12.1) K8S雲原生架構探索,玩轉前/後端監控與事件日誌大資料分析,高效能高可用+可擴充套件可伸縮叢集部署](https://mp.weixin.qq.com/s/5xYtkzNx31dLsCAhoMPGrQ)
6. [Sentry(v20.12.1) K8S 雲原生架構探索,Sentry JavaScript SDK 三種安裝載入方式](https://mp.weixin.qq.com/s/EV9M3Ru5rK5atAjTl1D9PA)
7. [Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT SDK 配置詳解](https://mp.weixin.qq.com/s/dlaejrn1kWBPiUJSmrzwow)
8. [Sentry(v20.12.1) K8S 雲原生架構探索, SENTRY FOR JAVASCRIPT 手動捕獲事件基本用法](https://mp.weixin.qq.com/s/4b4ojLkKGM6QX0z4Jq8nNQ)
9. [Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT Source Maps 詳解](https://mp.weixin.qq.com/s/-FySq0YUf2lJY2DjOORcIg)
10. [Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT 故障排除](https://mp.weixin.qq.com/s/BHyLOCI53EUoswUjm1-dXw)
11. [Sentry(v20.12.1) K8S 雲原生架構探索,1分鐘上手 JavaScript 效能監控](https://mp.weixin.qq.com/s/Z3Dp1fyzAEc5c89vy3Bzmw)
12. [Sentry(v20.12.1) K8S 雲原生架構探索,JavaScript 效能監控之管理 Transactions](https://mp.weixin.qq.com/s/Si2GLgGKsCwErJjJKFvtQg)
13. [Sentry(v20.12.1) K8S 雲原生架構探索,JavaScript 效能監控之取樣 Transactions](https://mp.weixin.qq.com/s/GdOFEE2aKVM7d5mWM1zVZw)
## Add Context
自定義上下文允許您將任意資料附加到事件。通常,此上下文在其生命週期中捕獲的任何 issue 之間都是共享的。您無法搜尋這些,但可以在 issue 頁面上檢視它們:
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141737234-550812083.png)
### Structured Context
附加自定義 data 的最佳實踐是通過結構化上下文。上下文必須始終是一個 dictionary 或 map,它的值可以是任意的。使用 `setContext` 並給 context 一個唯一的名稱:
```js
Sentry.setContext("character", {
name: "Mighty Fighter",
age: 19,
attack_type: "melee",
});
```
### Size Limitations
傳送上下文時,請考慮有效負載大小限制。 Sentry 不建議在上下文中傳送整個應用程式狀態和大資料 blob。如果超過最大有效負載大小,Sentry 將響應 `413 Payload Too Large`,並拒絕該事件。使用 `keepalive: true` 時,該請求可能會永遠保持待處理狀態。
### Passing Context Directly
從我們的 JavaScript SDK 5.16.0 版本開始,可以將某些上下文資料直接提供給 `captureException` 和 `captureMessage` 呼叫。提供的資料將與當前範圍內已經儲存的資料合併,除非使用回撥方法明確將其清除。
此功能有三種不同的變體形式:
1. 包含可更新屬性的普通物件
2. 我們將從中提取屬性的 Scope 例項
3. 回撥函式,它將接收當前 scope 作為引數並允許修改
我們允許傳遞以下上下文 keys:`tags`, `extra`, `contexts`, `user`, `level`, `fingerprint`。
**Example Usages**
```js
Sentry.captureException(new Error("something went wrong"), {
tags: {
section: "articles",
},
});
```
顯式清除已經儲存在 scope 中的內容:
```js
Sentry.captureException(new Error("clean as never"), scope => {
scope.clear();
scope.setTag("clean", "slate");
return scope;
});
```
使用 Scope 例項傳遞資料(其屬性仍將與全域性 scope 合併):
```js
const scope = new Sentry.Scope();
scope.setTag("section", "articles");
Sentry.captureException(new Error("something went wrong"), scope);
```
使用 Scope 例項傳遞資料並忽略全域性配置的 Scope 屬性:
```js
const scope = new Sentry.Scope();
scope.setTag("section", "articles");
Sentry.captureException(new Error("something went wrong"), () => scope);
```
### Clearing Context
Context 保留在當前 scope 內,因此在每個操作(請求等)結束時將其清除。您還可以 push 和 pop 自己的作用域,以將上下文資料應用於特定的程式碼塊或函式。
Sentry 支援兩種不同的 scope 來設定上下文:
1. global scope,Sentry 在操作結束時不會丟棄
2. 使用者建立的 scope
這將在以後的所有事件中更改:
```js
這將在以後的所有事件中更改:
```
僅針對在 `withScope` 回撥中捕獲的錯誤,將更改此狀態,然後自動將其恢復為先前的值:
```js
Sentry.withScope(function(scope) {
scope.setUser(someUser);
Sentry.captureException(error);
});
```
如果你想從作用域中(Scope)刪除全域性配置的資料,你可以呼叫:
```js
Sentry.configureScope(scope => scope.clear());
```
### Additional Data
除了結構化上下文(structured contexts),Sentry 還支援通過 `setExtra` 新增非結構化 "Additional Data"。**Additional Data 已經廢棄**,而應使用結構化上下文,並應儘可能避免使用。
## Identify Users
使用者包含一些關鍵資訊,這些資訊構成了 Sentry 中的唯一身份。每個選項都是可選的,但必須存在一個選項才能使Sentry SDK 捕獲使用者:
**id**: 您的使用者內部識別符號。
**username**: 使用者名稱。通常用作比內部 ID 更好的標籤。
**email**: username 的替代或補充。Sentry 知道電子郵件地址,並且可以顯示諸如 Gravatars 之類的內容並解鎖訊息傳遞功能。
**ip_address**: 使用者的 IP 地址。如果使用者未經身份驗證,Sentry 將 IP 地址用作使用者的唯一識別符號。Sentry 將嘗試從 HTTP 請求資料中提取此資訊(如果有)。設定為 `"{{auto}}"`,以使 Sentry 從 connection 中推斷 IP 地址。
此外,您可以提供保留名稱之外的任意 key/value 對,Sentry SDK 會將這些 `key/value 對`與 user 一起儲存。
識別使用者:
```js
Sentry.setUser({ email: "[email protected]" });
```
您還可以清除當前設定的 user:
```js
Sentry.configureScope(scope => scope.setUser(null));
```
## Set Transaction Name
當前 transaction 名稱用於對 Performance 產品中的 transactions 進行分組,並用 failure 點註釋錯誤事件。
transaction 名稱可以引用當前的 Web 應用程式路由或正在執行的當前 task。 例如:
* `GET /api/{version}/users/`
* `UserListView`
* `myapp.tasks.renew_all_subscriptions`
理想情況下,transaction 名稱不包含諸如使用者 ID 之類的變數值,但具有較低的基數,同時仍可以唯一地標識您所關心的程式碼。
我們的許多框架整合已經設定了 transaction 名稱。自己設定:
```js
Sentry.configureScope(scope => scope.setTransactionName("UserListView"));
```
這將覆蓋當前正在執行的 transaction 的名稱。
## Customize Tags
**Tags** 是既可索引又可搜尋的 key/value 字串對。Tags 具有強大的 UI 功能,例如過濾器(filters)和標籤分佈圖(tag-distribution maps)。Tags 還可以幫助您快速訪問相關事件,並檢視一組事件的標籤分佈(tag distribution)。Tags 的常見用法包括主機名(hostname),平臺版本(platform version)和使用者語言(user language)。
我們將自動為一個事件的所有 tags 建立索引,以及 Sentry 看到標籤的頻率和最後一次。我們還將跟蹤不同 tags 的數量,並可以幫助您確定各種 issues 的熱點。
定義 tags 很容易,並將它們繫結到 current scope,確保 scope 內的所有未來事件都包含相同的標籤:
```js
Sentry.setTag("page_locale", "de-at");
```
某些 tags 由 Sentry 自動設定。強烈建議您不要覆蓋這些 tags,而應使用自己的名稱命名。
一旦開始傳送標記的資料(tagged data),您將在 Sentry Web UI 中看到它:Project 頁面側欄中的過濾器(filters),在事件內進行彙總以及在聚合事件(aggregated event)的 tags 頁面上。
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141800130-2058419365.png)
## Attachments
Sentry 可以通過在事件旁邊儲存其他檔案(例如日誌檔案)作為附件來增強崩潰報告。 附件使崩潰中的檔案不僅可以上傳到Sentry,而且可以持久儲存以進行進一步調查。
### Uploading Attachments
要新增 attachment,請建立一個事件處理器(event processor),該事件處理器以 multipart form data 請求的形式將檔案上傳到附件端點。這需要使用其 ID 將附件與事件相關聯:
```js
public attachmentUrlFromDsn(dsn: Dsn, eventId: string) {
const { host, path, projectId, port, protocol, user } = dsn;
return `${protocol}://${host}${port !== '' ? `:${port}` : ''}${
path !== '' ? `/${path}` : ''
}/api/${projectId}/events/${eventId}/attachments/?sentry_key=${user}&sentry_version=7&sentry_client=custom-javascript`;
}
Sentry.addGlobalEventProcessor((event: Event) => {
try {
const client = Sentry.getCurrentHub().getClient();
const endpoint = attachmentUrlFromDsn(
client.getDsn(),
event.event_id
);
const formData = new FormData();
formData.append(
'my-attachment',
new Blob([JSON.stringify({ logEntries: ["my log"] })], {
type: 'application/json',
}),
'logs.json'
);
fetch(endpoint, {
method: 'POST',
body: formData,
}).catch((ex) => {
// we have to catch this otherwise it throws an infinite loop in Sentry
console.error(ex);
});
return event;
} catch (ex) {
console.error(ex);
}
});
```
Sentry 每個事件最多允許 100MB 的附件,包括崩潰報告檔案(如果適用)。超過此大小的上傳將被 HTTP 錯誤 `413 Payload Too Large` 拒絕,並且資料將立即被丟棄。要新增更大或更多的檔案,請考慮使用輔助儲存選項。
附件存留 30 天;如果超出了配額中包含的總儲存空間,則不會儲存附件。您可以隨時刪除附件或其包含的事件。刪除附件不會影響您的配額(quota) - Sentry 儲存附件後立即將其計入您的配額。
**Access to Attachments**
要限制對附件的訪問,請導航到您組織的 **General Settings**,然後選擇 Attachments Access 下拉選單來設定適當的訪問許可權 - 您的組織的任何成員、組織帳單所有者、成員(member)、管理員(admin)、經理(manager)或所有者(owner)。
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141813947-1235914472.png)
預設情況下,啟用儲存後,將授予所有成員訪問許可權。如果成員無權訪問該專案,則無法下載附件。該按鈕將在 Sentry 中顯示為灰色。成員只能檢視附件已儲存。
### Viewing Attachments
附件顯示在所顯示事件的 **Issue Details** 頁面的底部。
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141825753-237426388.png)
或者,附件也會顯示在 **Issue Details** 頁面上的 Attachments 選項卡中,您可以在其中檢視附件的型別以及相關事件。單擊 Event ID,以開啟該特定事件的 **Issue Details** 資訊。
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141835483-1225242830.png)
## Breadcrumbs
Sentry 使用 breadcrumbs 建立事件發生之前的事件線索。這些事件與傳統日誌非常相似,但是可以記錄更豐富的結構化資料。
此頁面概述了手動 breadcrumb 錄製(recording)和自定義(customization)。瞭解有關 **Issue Details** 頁面上顯示的資訊的更多資訊,以及如何過濾 breadcrumbs 以快速解決 Using Breadcrumbs 中的問題。
### Manual Breadcrumbs
每當發生有趣的事情時,您都可以手動新增 breadcrumbs。例如,如果使用者進行身份驗證或發生其他狀態更改,則可以手動記錄一個麵包屑。
```js
Sentry.addBreadcrumb({
category: "auth",
message: "Authenticated user " + user.email,
level: Sentry.Severity.Info,
});
```
可用的 breadcrumb keys 包括 `type`, `category`, `message`, `level`, `timestamp`(許多SDK會自動為您設定)和 `data`,在此處可以放置您希望包含麵包屑的任何其他資訊。使用這六個 key 以外的 key 不會導致錯誤,但是會導致在由 Sentry 處理事件時刪除資料。
### Automatic Breadcrumbs
SDK 及其相關的整合將自動記錄許多型別的 breadcrumbs。例如,瀏覽器 JavaScript SDK 將自動記錄所有 location 更改。
### Customize Breadcrumbs
SDK 允許您通過 `before_breadcrumb` 掛鉤自定義 breadcrumbs。此掛鉤傳遞了已經組裝好的 breadcrumb,並且在某些SDK 中傳遞了可選 hint。該函式可以修改 breadcrumb 或通過返回 `null` 決定完全放棄它:
```js
Sentry.init({
// ...
beforeBreadcrumb(breadcrumb, hint) {
return breadcrumb.category === "ui.click" ? null : breadcrumb;
},
});
```
## User Feedback
當用戶遇到錯誤時,Sentry 可以收集其他反饋。當您通常可以呈現簡單的錯誤頁面(經典的`500.html`)時,這種型別的反饋非常有用。
要收集 feedback,請使用可嵌入的 JavaScript widget,該小部件將請求並收集使用者的姓名,電子郵件地址以及發生的情況的描述。提供反饋後,Sentry 會將反饋與原始事件配對,從而使您對問題有更多見解。
下面的螢幕截圖提供了 User Feedback 小部件的示例,儘管您的個性化可能因您的自定義而有所不同:
![](https://img2020.cnblogs.com/blog/436453/202101/436453-20210125141854910-2040892752.png)
### Collecting Feedback
要整合 widget,您需要執行 2.1 版或更高版本的 JavaScript SDK。該 widget 將使用您的公共 DSN 進行身份驗證,然後傳遞在後端生成的 Event ID。
**如果您希望使用 widget 的替代產品,或者沒有 JavaScript 前端,則可以使用 User Feedback API。**
確保您有可用的 JavaScript SDK:
```html
```
如果您使用的是 [React](/platforms/javascript/guides/react/) 或 [Angular](/platforms/javascript/guides/angular/) 之類的框架,則收集使用者反饋的最佳位置是您的錯誤處理元件。(有關示例,請參閱特定於平臺的文件。)如果您不使用框架,則可以在傳送事件之前使用 `beforeSend` 收集反饋:
```html
```
### Customizing the Widget
您可以根據組織的需要自定義視窗小部件,尤其是為了本地化目的。所有選項都可以通過 `showReportDialog` 呼叫傳遞。
Sentry 的自動語言檢測 override(例如 `lang=de`)
| Param | Default |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| `eventId` | 手動設定事件的ID。 |
| `dsn` | 手動設定要報告的dsn。 |
| `user` | 手動設定 user data [具有下面列出的 key 的物件]。 |
| `user.email` | 使用者的電子郵件地址。 |
| `user.name` | 使用者名稱。 |
| `lang` | _[automatic]_ – 覆蓋 Sentry 的語言程式碼 |
| `title` | 看來我們遇到了問題。 |
| `subtitle` | 我們的團隊已收到通知。 |
| `subtitle2` | 如果您想提供幫助,請告訴我們下面發生的情況。 – **在小螢幕解析度下不可見** |
| `labelName` | 名稱 |
| `labelEmail` | Email |
| `labelComments` | 發生了什麼? |
| `labelClose` | 關閉 |
| `labelSubmit` | 提交 |
| `errorGeneric` | 提交報告時發生未知錯誤。 請再試一次。 |
| `errorFormEntry` | 有些欄位無效。請更正錯誤,然後重試。 |
| `successMessage` | 您的反饋已傳送。 謝謝! |
| `onLoad` | n/a |
## Scopes and Hubs
捕獲事件並將其傳送到 Sentry 後,SDK 會將事件資料與當前作用域(scope)中的額外資訊合併。SDK 通常會在框架整合中為您自動管理 scopes,而您無需考慮它們。但是,您應該知道什麼是 scope 以及如何利用它來發揮自己的優勢。
### What's a Scope, what's a Hub
您可以將 hub 視為我們的 SDK 用於將事件路由到 Sentry 的中心點。呼叫 `init()` 時,將建立一個 hub,並在其上建立一個 client 和一個 blank scope。然後,該 hub 與當前執行緒相關聯,並將在內部儲存一堆 scopes。
scope 將包含應與事件一起傳送的有用資訊。例如,contexts 或 breadcrumbs 儲存在 scope 上。當推入作用域時,它將繼承父作用域的所有資料,並且當其彈出時,所有修改都將還原。
預設的 SDK 整合將智慧地推送和彈出作用域。例如,Web 框架整合將在您的路由(routes)或控制器(controllers)周圍建立和銷燬作用域。
### How do the Scope and Hub Work
當您開始使用 SDK 時,將自動為您建立一個 scope 和 hub。hub 不太可能直接與之互動,除非您正在編寫整合或希望建立或銷燬作用域。另一方面,作用域更多地面向用戶。您可以隨時呼叫 `configure-scope` 修改儲存在 scope 上的資料。例如,這用於 modify the context。
當您在內部呼叫諸如 `capture_event` 之類的全域性函式時,Sentry 會發現當前的 hub 並要求其捕獲事件。然後,hub 將在內部將事件與最高 scope 的資料合併。
### Configuring the Scope
使用範圍時,最有用的操作是 `configure-scope` 函式。它可用於重新配置當前 scope。例如,這可用於新增自定義標籤或向 sentry 告知當前已通過身份驗證的使用者。
```js
Sentry.configureScope(function(scope) {
scope.setTag("my-tag", "my value");
scope.setUser({
id: 42,
email: "[email protected]",
});
});
```
這也可以在登出時取消使用者設定時應用:
```js
Sentry.configureScope(scope => scope.setUser(null));
```
### Local Scopes
我們還支援一鍵式推送和配置 scope。通常將其稱為 `with-scope` 或 `push-scope`,如果您只想傳送一個特定事件的資料,這也非常有用。在下面的示例中,我們使用該函式將 `level` 和 `tag` 附加到僅一個特定錯誤:
```js
Sentry.withScope(function(scope) {
scope.setTag("my-tag", "my value");
scope.setLevel("warning");
// will be tagged with my-tag="my value"
Sentry.captureException(new Error("my error"));
});
// will not be tagged with my-tag
Sentry.captureException(new Error("my other error"));
```
儘管此示例看起來與 `configure-scope` 相似,但有很大的不同,從某種意義上說 `configure-scope` 實際上會更改當前的 active scope,所有對 `configure-scope` 的後續呼叫都將保留所做的更改。
另一方面,使用 with-scope 會建立當前作用域的副本,並保持隔離狀態,直到函式呼叫完成。因此,您可以在此處不想設定其他位置的上下文資訊,也可以通過在作用域上呼叫 `clear` 來根本不附加任何上下文資訊,而“全域性”範圍保持不變。
中文文件陸續同步到:
* https://getsentry.hacker-linner.com
```
我是為少。
微信:uuhells123。
公眾號:黑客下午茶。
謝謝點贊支援