內容整理於官方開發文件
系列
- Docker Compose 部署與故障排除詳解
- K8S + Helm 一鍵微服務部署
- Sentry 開發者貢獻指南 - 前端(ReactJS生態)
- Sentry 開發者貢獻指南 - 後端服務(Python/Go/Rust/NodeJS)
- Sentry 開發者貢獻指南 - 前端 React Hooks 與蟲洞狀態管理模式
效能監控指南
本文件介紹了 SDK
應如何通過分散式跟蹤新增對效能監控的支援。
這應該提供 SDK
需要實現的 API
的概述,而不強制要求內部實現細節。
參考實現:
SDK 配置
通過設定兩個新的 SDK
配置選項之一來啟用跟蹤,tracesSampleRate
和 tracesSampler
。如果未設定,則兩者都預設為 undefined
,從而選擇如何加入跟蹤。
tracesSampleRate
這應該是介於 0.0
和 1.0
(含)之間的 float/double
,表示任何給定 transaction
將被髮送到 Sentry
的百分比機會。
因此,0.0
是 0%
的機會(不會傳送),而 1.0
是 100%
的機會(都將傳送)。
此 rate
同樣適用於所有 transaction
;
換句話說,每個 transaction
都應該有相同的隨機機會以 sampled = true
結束,等於 tracesSampleRate
。
tracesSampler
這應該是一個 callback
,在 transaction
開始時呼叫,它將被賦予一個 samplingContext
物件,並且應該返回一個介於 0.0
和 1.0
之間的取樣率_對於所討論的 transaction_。
此取樣率的行為方式應與上面的 tracesSampleRate
相同,不同之處在於它僅適用於新建立的 transaction
,因此可以以不同的 rate
對不同的 transaction
進行取樣。
返回 0.0
應該強制刪除 transaction
(設定為 sampled = false
),返回 1.0
應該強制傳送 transaction
(設定 sampled = true
)。
可選地,tracesSampler
callback 也可以返回一個布林值來強制進行取樣決策(false
等同於 0.0
,true
等同於 1.0
)。
如果返回兩種不同的資料型別在實現語言中不是一個選項,則可以安全地省略這種可能性。
maxSpans
由於 transaction
payload 在攝取端強制執行最大大小,因此 SDK
應限制附加到事務的 span
數。
這類似於如何限制麵包屑
和其他任意大小的列表以防止意外誤用。
如果在達到最大值後新增新的 span
,SDK
應刪除 span
並理想地使用內部日誌記錄來幫助除錯。
maxSpans
應該作為一個內部的、不可配置的、預設為 1000
的常量來實現。如果在給定的平臺中有理由,它可能會變得可配置。
maxSpans
限制還可以幫助避免永遠不會完成的 transaction
(在 span
開啟時保持 transaction
開啟的平臺中),防止 OOM
錯誤,並通常避免降低應用程式效能。
Event
變更
在撰寫本文時,transaction
是作為 Event
模型的擴充套件實現的。
Transaction
的顯著特徵是 type: "transaction"
。
除此之外,Event
獲得了新的欄位:spans
、contexts.TraceContext
。
新的 Span
和 Transaction
類
在記憶體中,span
構建了一個定時操作的概念樹(conceptual tree)
。
我們稱整個 span tree
為 transaction
。
有時我們使用術語 "transaction"
來指代作為整棵樹的 span tree
,有時特指樹的 root span
。
通過網路,transaction
被序列化為 JSON
作為增強的 Event
,並作為 envelope
傳送。
不同的 envelope
型別用於優化攝取(因此我們可以以不同於其他事件的方式路由 “transaction events”
,主要是 “error events”
)。
在 Sentry UI
中,您可以使用 Discover
檢視所有型別的事件,並使用 Issues
和 Performance
部分分別深入研究 errors
和 transactions
。
面向使用者的跟蹤文件解釋了更多產品級別的概念。
Span
類將每個單獨的 span
儲存在 trace
中。
Transaction
類就像一個 span
,有幾個主要區別:
Transaction
有name
,span
沒有。- 在
span
上呼叫finish
方法會記錄span
的結束時間戳。對於transaction
,finish
方法另外向Sentry
傳送一個事件。
Transaction
類可能繼承自 Span
,但這是一個實現細節。
從語義上講,transaction
既表示 span tree
的 top-level span
,也表示向 Sentry
報告的單位。
-
Span
介面- 建立
Span
時,將startTimestamp
設定為當前時間 SpanContext
是Span
的屬性集合(可以是一個實現細節)。如果可能,SpanContext
應該是不可變的。Span
應該有一個方法startChild
,它使用當前span
的id
作為新span
的parentSpanId
建立一個新的span
,並將當前span
的sampled
值複製到新span
的sampled
屬性startChild
方法應遵守maxSpans
限制,一旦達到限制,SDK
不應為給定的transaction
建立新的子span
。Span
應該有一個名為toSentryTrace
的方法,它返回一個字串,該字串可以作為名為sentry-trace
的header
傳送。Span
應該有一個名為iterHeaders
(適應平臺的命名約定)的方法,它返回一個可迭代的或header
名稱和值的對映。這是一個包含return {"sentry-trace": toSentryTrace()}
的薄wrapper
。 請參閱continueFromHeaders
以瞭解為什麼存在這種情況,並且在編寫整合(integration)
時應該首選。
- 建立
-
Transaction
介面- 一個
Transaction
內部包含一個子Span
的平面列表(不是樹結構) Transaction
還有一個setName
方法來設定transaction
的名稱Transaction
在建立時收到一個TransactionContext
(新屬性與SpanContext
是name
)- 由於
Transaction
繼承了Span
,因此它具有所有Span
可用的函式並且可以像Span
一樣進行互動 - 一個
transaction
要麼被取樣(sampled = true
),要麼被取消取樣(sampled = false
),一個在transaction
的生命週期中被繼承或設定一次的決定,並且在任何一種情況下都會傳播給所有的children
。不應將未抽樣的transaction
傳送給Sentry
。 TransactionContext
應該有一個叫做fromSentryTrace
的static/ctor
方法,它用從sentry-trace
header值接收的資料預填充一個TransactionContext
TransactionContext
應該有一個名為continueFromHeaders(headerMap)
的static/ctor
方法,它現在實際上只是一個圍繞fromSentryTrace(headerMap.get("sentry-trace"))
的薄wrapper
。integration/framework-sdk
的作者應該更喜歡fromSentryTrace
,因為它隱藏了核心sdk
中更深層次使用的確切header
名稱,併為將來使用其他header
(來自W3C
)留下了機會,而無需更改所有整合。
- 一個
-
Span.finish()
- 只需將
endTimestamp
設定為當前時間(在 payloadtimestamp
中)
- 只需將
-
Transaction.finish()
super.finish()
(在 Span 上呼叫 finish)- 僅當
sampled == true
時才將其傳送給Sentry
- 一個
Transaction
需要被包裹在一個Envelope
中併傳送到Envelope Endpoint
Transport
應該為Transactions
/Events
使用相同的內部佇列Transport
應該實現基於類別的速率限制 →Transport
應該處理在內部將Transaction
包裝在Envelope
中
取樣
每個 transaction
都有一個 “抽樣決策”
,即一個布林值,指示是否應該將其傳送給 Sentry
。
這應該在 transaction
的生命週期內只設定一次,並且應該儲存在內部的 sampled
布林值中。
transaction
可以通過多種方式結束抽樣決策(sampling decision)
:
- 根據
tracesSampleRate
中設定的靜態取樣率
隨機取樣 - 根據
tracesSampler
返回的動態取樣率
進行隨機取樣 tracesSampler
返回的絕對決策(100%
概率或0%
概率)- 如果
transaction
有父級,繼承其父級的抽樣決策
- 傳遞給
startTransaction
的絕對決策
當其中一個以上發揮作用的可能性時,應適用以下優先規則:
- 如果將
抽樣決策
傳遞給startTransaction
(startTransaction({name: "my transaction", sampled: true})
),則將使用該決策,而不管其他任何事情。 - 如果定義了
tracesSampler
,則將使用其決策
。它可以選擇保留或忽略任何父取樣決策
,或使用取樣上下文資料
做出自己的決策或為transaction
選擇取樣率
。 - 如果未定義
tracesSampler
,但存在父取樣決策,則將使用父取樣決策。 - 如果沒有定義
tracesSampler
並且沒有父取樣決策,則將使用tracesSampleRate
。
Transaction
應僅通過tracesSampleRate
或tracesSampler
進行取樣。sampleRate
配置用於error
事件,不應應用於transaction
。
取樣上下文
如果定義,tracesSampler
回撥應該傳遞一個 samplingContext
物件,該物件至少應該包括:
- 建立
transaction
的transactionContext
- 一個布林值
parentSampled
,包含從父級傳遞過來的取樣決策
,如果有的話 - 來自可選的
customSamplingContext
物件的資料在手動呼叫時傳遞給startTransaction
根據平臺,可能包含其他預設資料。(例如,對於伺服器框架,包含與 transaction
正在測量的請求相對應的 request
物件是有意義的。)
傳播
transaction
的抽樣決策
應傳遞給其所有子項,包括跨服務邊界。這可以在相同服務子項的 startChild
方法中完成,併為不同服務中的子項使用 senry-trace
header。
Header sentry-trace
Header
用於跟蹤傳播。SDK
使用 header
繼續跟蹤來自上游服務(傳入 HTTP
請求),並將跟蹤資訊傳播到下游服務(傳出 HTTP
請求)。
sentry-trace = traceid-spanid-sampled
sampled
是可選的。所以至少,它是預期的:
sentry-trace = traceid-spanid
為了與 W3C traceparent
header(沒有版本字首)
和 Zipkin's b3
headers(考慮 64
位和 128
位的 traceId
有效)提供最小的相容性,
sentry-trace
header 應具有以 32
個十六進位制字元編碼的 128
位的 traceId
以及以 16
個十六進位制字元編碼的 64
位 spanId
。
為了避免與 W3C traceparent
header(我們的 header
相似但不相同)混淆,
我們將其簡稱為 sentry-trace
。header
中沒有定義版本。
- https://www.w3.org/TR/trace-context/#traceparent-header
- https://zipkin.io/pages/instrumenting#communicating-trace-information
sampled
值
為簡化處理,該值由單個(可選)字元組成。可能的值為:
- No value means defer
0 - Don't sample
1 - Sampled
與 b3
header 不同,sentry-trace
header 不應該只包含一個取樣決策
,沒有 traceid
或 spanid
值。有很好的理由 無論取樣決策如何,始終包含 traceid
和 spanid
,這樣做也簡化了實現。
除了在 Sentry
的情況下使用 *defer 的通常原因外,
還有一個原因是下游系統使用 Sentry
捕獲 error
事件。可以在那時做出決定,對跟蹤進行取樣,以便為報告的崩潰提供跟蹤資料。
sentry-trace = sampled
這實際上對於代理將其設定為 0
並選擇退出跟蹤很有用。
Static API 變更
Sentry.startTransaction
函式應該接受兩個引數 - 傳遞給 Transaction
建構函式的 transactionContext
和一個包含要傳遞給 tracesSampler
(如果已定義)的資料的可選的 customSamplingContext
物件。
它建立一個繫結到當前 hub
的 Transaction
並返回例項。
使用者與例項互動以建立子 span
,因此,必須自己跟蹤它。
Hub
變更
-
引入一個名為
traceHeaders
的方法- 此函式返回
header
(string)sentry-trace
- 該值應該是當前在
Scope
上的Span
的trace header
字串
- 此函式返回
-
引入一個名為
startTransaction
的方法- 採用與
Sentry.startTransaction
相同的兩個引數 - 建立一個新的
Transaction
例項 - 應按照本文件
'Sampling'
部分中更詳細的描述實施抽樣
- 採用與
-
修改名為
captureEvent
或captureTransaction
的方法- 不要為
transaction
設定lastEventId
- 不要為
Scope
變更
Scope
持有對當前 Span
或 Transaction
的引用。
Scope
引入setSpan
- 這可以在內部使用,來傳遞
Span
/Transaction
,以便整合可以將子項附加到它 - 在
Scope
(舊版)上設定transaction
屬性應該覆蓋儲存在Scope
中的Transaction
的名稱,如果有的話。
這樣,即使使用者無法直接訪問Transaction
的例項,我們也可以讓使用者選擇更改transaction
名稱。
- 這可以在內部使用,來傳遞
與 beforeSend
和事件處理器的互動
beforeSend
回撥是我們認為最重要的特殊 Event Processor
。適當的事件處理器通常被認為是內部的。
Transaction
應該不通過 beforeSend
。但是,它們仍然由事件處理器
處理。
這是在將 transaction
作為 event
的當前實現處理的一些靈活性與為 transaction
和 span
的不同生命週期 hook
留出空間之間的折衷。
動機:
-
面向未來:如果使用者依賴
beforeSend
進行transaction
,
這將使最終在不破壞使用者程式碼的情況下實現單個span
攝取變得複雜。
在撰寫本文時,transaction
作為event
傳送,但這被視為實現細節。 -
API 相容性:使用者擁有他們現有的
beforeSend
實現,只需要處理錯誤事件。
我們將transaction
作為一種新型event
引入。
當使用者升級到新的SDK
版本並開始使用跟蹤時,他們的beforeSend
將開始看到他們的程式碼不打算處理的新型別。
在transaction
之前,他們根本不必關心不同的事件型別。
有幾種可能的後果:破壞使用者應用程式;默默地和無意地放棄transaction
;
transaction
事件以令人驚訝的方式修改。 -
就可用性而言,
beforeSend
不適合刪除transaction
,就像刪除error
一樣。
Error
是一個時間點事件。當error
發生時,使用者在beforeSend
中有完整的上下文,
並且可以在它進入Sentry
之前修改/丟棄
事件。對於交易,transaction
是不同的。
建立transaction
,然後將它們開啟一段時間,同時建立child span
並將其附加到它。
同時傳出的HTTP
請求包括當前transaction
與其他服務的取樣決策
。
在span
和transaction
完成後,將transaction
放入類似beforeSend
的鉤子中會在跟蹤中留下來自其他服務的孤立transaction
。
同樣,在此後期將取樣決策
修改為"yes"
也會產生不一致的痕跡。
跟蹤上下文(實驗性)
為了對跟蹤進行取樣,我們需要沿著呼叫鏈傳遞 trace id
以及做出取樣決策
所需的資訊,即所謂的 跟蹤上下文(trace context)
。
協議
Trace
資訊作為編碼的 tracestate
header 在 SDK
之間傳遞,SDK
預計會攔截和傳播這些 header
。
對於向 sentry
提交的事件,trace context
作為嵌入在 Envelope header
中的 JSON
物件傳送,key
為 trace
。
跟蹤上下文
無論採用何種傳輸機制,trace context
都是具有以下欄位的 JSON
物件:
trace_id
(string, required) -UUID V4
編碼為不帶破折號的十六進位制序列(例如771a43a4192642f0b136d5159a501700
),它是一個由32
個十六進位制數字組成的序列。這必須與提交的transaction item
的trace id
匹配。public_key
(string, required) - 來自SDK
使用的DSN
的Public key
。它允許Sentry
通過基於起始專案解析相同的規則集來對跨多個專案的跟蹤進行取樣。release
(string, optional) - 客戶端選項中指定的版本名稱,通常是:package@x.y.z+build
。 這應該與transaction event payload
的release
屬性匹配*environment
- 客戶端選項中指定的environment
名稱,例如staging
。 這應該與transaction event payload
的environment
屬性匹配*user
(object, optional) - 包含以下欄位的scope
的user context
的子集:id
(string, optional) - 使用者上下文的id
屬性。segment
(string, optional) - 使用者資料包中的segment
屬性值(如果存在)。將來,該欄位可能會被提升為使用者上下文的適當屬性。
transaction
(string, optional) - 在scope
上設定的transaction
名稱。這應該與transaction event payload
的transaction
屬性匹配*
例子:
{
"trace_id": "771a43a4192642f0b136d5159a501700",
"public_key": "49d0f7386ad645858ae85020e393bef3",
"release": "myapp@1.1.2",
"environment": "production",
"user": {
"id": "7efa4978da177713df088f846f8c484d",
"segment": "vip"
},
"transaction": "/api/0/project_details"
}
Envelope Headers(信封頭)
當通過 Envelope
向 Sentry
傳送 transaction
事件時,必須在 trace
欄位下的 envelope header
中設定 trace
資訊。
這是一個包含 trace context
的最小 envelope header
的示例(儘管 header
不包含換行符,但在下面的示例中新增了換行符以提高可讀性):
{
"event_id": "12c2d058d58442709aa2eca08bf20986",
"trace": {
"trace_id": "771a43a4192642f0b136d5159a501700",
"public_key": "49d0f7386ad645858ae85020e393bef3"
// other trace attributes
}
}
Tracestate Headers(跟蹤狀態頭)
將跟蹤上下文
傳播到其他 SDK
時,Sentry
使用 W3C tracestate
header。有關如何將這些 header
傳播到其他 SDK
的更多資訊,請參閱 "Trace Propagation"
。
Tracestate
header 包含幾個特定於供應商的不透明資料。根據 HTTP
規範,這些多個 header
值可以通過兩種方式給出,通常由 HTTP
庫和開箱即用的框架支援:
- 用逗號連線:
tracestate: sentry=<data>,other=<data>
- 重複:
tracestate: sentry=<data> tracestate: other=<data>
要建立 tracestate header
的內容:
- 將完整的
trace context
序列化為JSON
,包括trace_id
。 - 如果字串在平臺上的表示方式不同,則將生成的
JSON
字串編碼為UTF-8
。 - 使用
base64
對UTF-8
字串進行編碼。 - 去除尾隨填充字元 (
=
),因為這是一個保留字元。 - 在前面加上
"sentry="
,導致"sentry=<base64>"
。 - 如上所述加入
header
。
通過去除尾隨填充,預設的
base64
解析器可能會檢測到不完整的payload
。選擇允許丟失=
或允許截斷payload
的解析模式。
例如:
{
"trace_id": "771a43a4192642f0b136d5159a501700",
"public_key": "49d0f7386ad645858ae85020e393bef3",
"release": "1.1.22",
"environment": "dev",
"user": {
"segment": "vip",
"id": "7efa4978da177713df088f846f8c484d"
}
}
將編碼為
ewogICJ0cmFjZV9pZCI6ICI3NzFhNDNhNDE5MjY0MmYwYjEzNmQ1MTU5YTUwMTcwMCIsCiAgInB1YmxpY19rZXkiOiAiNDlkMGY3Mzg2YWQ2NDU4NThhZTg1MDIwZTM5M2JlZjMiLAogICJyZWxlYXNlIjogIjEuMS4yMiIsCiAgImVudmlyb25tZW50IjogImRldiIsCiAgInVzZXIiOiB7CiAgICAic2VnbWVudCI6ICJ2aXAiLAogICAgImlkIjogIjdlZmE0OTc4ZGExNzc3MTNkZjA4OGY4NDZmOGM0ODRkIgogIH0KfQ
並導致 header
tracestate: sentry=ewogIC...IH0KfQ,other=[omitted]
(注意 header
末尾的第三方條目;新的或修改的條目總是新增到左側,因此我們將 sentry=
值放在那裡。另請注意,儘管此處為了清晰起見省略了編碼值, 在真正的 header 中,將使用完整的值。)
實施指南
支援此 header
的 SDK
必須:
- 建立新的
trace context
時使用scope
資訊 - 為包含
transaction
的envelope
新增帶有trace context
的envelope header
- 將
tracestate
HTTP header 新增到傳出的 HTTP 請求以進行傳播 - 在適用的情況下攔截對
tracestate
HTTP header 的傳入HTTP
請求,並將它們應用到local trace context
背景
這是效能指南
涵蓋的 trace ID
傳播的擴充套件。
根據統一 API 跟蹤規範
,Sentry SDK
通過整合向傳出請求新增 HTTP header sentry-trace
。
最重要的是,此 header
包含 trace ID
,它必須與 transaction event
的 trace id
以及下面的 trace context
的 trace id
匹配。
trace context
應在 W3C traceparent header 中定義的附加 tracestate
header 中傳播。
請注意,我們必須保持與 W3C
規範的相容性,而不是專有的 sentry-trace
header。
除了 Sentry SDK
放置的內容之外,tracestate
header 還包含供應商特定的不透明資料。
Client 選項
雖然 trace context
正在開發中,但它們應該在內部 trace_sampling
布林值 client
選項後面進行門控。該選項預設為 false
,不應在 Sentry
文件中記錄。
根據平臺命名指南,該選項應該適當地區分大小寫:
trace_sampling
(snake case)traceSampling
(camel case)TraceSampling
(pascal case)setTraceSampling
(Java-style setters)
新增 Envelope Header
在以下任何一種情況下,SDK
應將 envelope header
新增到傳出 envelope
中:
envelope
包含transaction event
。scope
有一個transaction
繫結。
具體來說,這意味著即使沒有 transaction
的 envelope
也可以包含 trace
envelope header,
從而允許 Sentry
最終對屬於 transaction
的 attachment
進行取樣。
當 envelope
包含 transaction
且 scope
有繫結 transaction
時,
SDK
應使用 envelope
的 transaction
來建立 trace
envelope header。
凍結上下文
為了確保 trace
中所有 transaction
的 trace context
完全一致,一旦通過網路傳送 trace context
,就不能更改 trace context
,即使 scope
或 options
之後發生更改。
也就是說,一旦計算出 trace context
就不再更新。即使應用程式呼叫 setRelease
,舊版本仍保留在 context
中。
為了彌補對 setTransaction
和 setUser
等函式的延遲呼叫,
可以認為 trace context
處於兩種狀態:NEW 和 SENT。
最初,context
處於 NEW 狀態並且可以修改。第一次傳送後,它將變為 SENT 並且不能再更改。
我們建議 trace context
應該在第一次需要時即時計算:
- 建立
Envelope
- 傳播到傳出的
HTTP
請求
Trace context
必須保留,直到使用者開始新的 trace
,此時 SDK
必須計算新的 trace context
。
建議
SDK
記錄在trace context
凍結時會導致trace context
更改的屬性修改,例如user.id
,以簡化常見動態取樣
陷阱的除錯。
傳入上下文
與攔截來自入站 HTTP
請求的 trace ID
相同,SDK
應讀取 tracestate
header 並假設 Sentry 跟蹤上下文(如果指定)。這樣的上下文立即凍結在 SENT 狀態,不應再允許修改。
平臺細節
在 JavaScript 中編碼
如前所述,我們需要使用 UTF-8
字串對 JSON trace context
進行編碼。JavaScript
內部使用 UTF16
,因此我們需要做一些工作來進行轉換。
Base64 encoding and decoding in JavaScript(以及 Using Javascript's atob to decode base64 doesn't properly decode utf-8 strings)介紹了基本思想。
- https://attacomsian.com/blog/javascript-base64-encode-decode
- https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
簡而言之,這是將 context
轉換為可以儲存在 tracestate
中的 base64
字串的函式。最後我們採用了一個更簡單的實現,但想法是一樣的:
// Compact form
function objToB64(obj) {
const utf16Json = JSON.stringify(obj);
const b64 = btoa(
encodeURIComponent(utf16Json).replace(
/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode("0x" + p1);
}
)
);
const len = b64.length;
if (b64[len - 2] === "=") {
return b64.substr(0, len - 2);
} else if (b64[len - 1] === "=") {
return b64.substr(0, len - 1);
}
return b64;
}
// Commented
function objToB64(obj) {
// object to JSON string
const utf16Json = JSON.stringify(obj);
// still utf16 string but with non ASCI escaped as UTF-8 numbers)
const encodedUtf8 = encodeURIComponent(utf16Json);
// replace the escaped code points with utf16
// in the first 256 code points (the most wierd part)
const b64 = btoa(
endcodedUtf8.replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) {
return String.fromCharCode("0x" + p1);
})
);
// drop the '=' or '==' padding from base64
const len = b64.length;
if (b64[len - 2] === "=") {
return b64.substr(0, len - 2);
} else if (b64[len - 1] === "=") {
return b64.substr(0, len - 1);
}
return b64;
}
// const test = {"x":"a-?-讀寫漢字 - 學中文"}
// objToB64(test)
// "eyJ4IjoiYS3wn5mCLeivu+WGmeaxieWtlyAtIOWtpuS4reaWhyJ9"
這是接受 base64
字串(帶或不帶 '=' 填充)並返回一個物件的函式
function b64ToObj(b64) {
utf16 = decodeURIComponent(
atob(b64)
.split("")
.map(function(c) {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
})
.join("")
);
return JSON.parse(utf16);
}
// b64ToObj("eyJ4IjoiYS3wn5mCLeivu+WGmeaxieWtlyAtIOWtpuS4reaWhyJ9")
// {"x":"a-?-讀寫漢字 - 學中文"}
帶有命令列實用程式的 Base64
GNU base64
命令列實用程式帶有一個開關來包裝編碼的字串。
這與 tracestate
header 不相容,應該避免。
如果 base64
實現建立多行,則必須將它們連線在一起。
Span Operations(跨度操作)
Span
操作是識別 span
正在測量的操作型別的短程式碼。
Span
操作是低基數屬性 - 它們應該儘可能通用,同時仍然是人類可讀和有用的。他們應該避免包含高基數資料,如 ID
和 URL
。
操作應儘可能遵循 OpenTelemetry 的語義約定。
保持 SDK
和 integration
之間的類別一致很重要,因為 Sentry
在操作細分功能中使用它們。
例如,db.init
和db.query
都將被歸類為資料庫操作(db
)。可以在projectoptions/defaults.py 檢視預設操作細分配置。
- https://docs.sentry.io/product/sentry-basics/tracing/event-detail/#operations-breakdown
- https://github.com/getsentry/sentry/blob/809b7fe54c6f06cc1e4c503cf83ded896472a011/src/sentry/projectoptions/defaults.py#L74
操作列表
下表包含 SDK
和 Sentry
產品使用的操作示例。
表中的 Usage
列包含使用該操作類別
的示例,但不是操作用法
的硬性建議
。
只要類別保持一致,SDK
開發人員就可以自由選擇最適合他們正在檢測的用例的操作
和識別符號
。
如果未提供 span
操作,則使用 default
的值。
Browser
Category | Usage | Description |
---|---|---|
pageload | Web 應用程式的完整頁面載入 | |
navigation | Web 應用程式中的客戶端瀏覽器 history 更改 | |
resource | 資源,根據效能資源計時 | |
resource.script | ||
resource.link | ||
resource.css | ||
resource.img | ||
browser | 瀏覽器 API 或功能的使用 | |
browser.paint | ||
mark | performance.mark() API 的使用 | |
measure | performance.measure() API 的使用 | |
ui | ||
ui.animation | 一個 animation | |
ui.render | 渲染 UI 元素所需的時間 | |
ui.update | 更新 UI 元素所需的時間 |
- https://w3c.github.io/resource-timing/#sec-performanceresourcetiming
- https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
- https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
JS Frameworks
JS 框架應該在 UI
元件相關的操作前加上 ui
類別。
Category | Usage | Description |
---|---|---|
ui.react | 與 React 元件相關的 Span | |
ui.react.mount | ||
ui.react.render | ||
ui.vue | 與 Vue.js 元件相關的 Span | |
ui.vue.mount | ||
ui.vue.update | ||
ui.angular | 與 Angular 元件相關的 Span | |
ui.ember | 與 EmberJS 元件相關的 Span |
Web Server
Web server
相關的 span
應該儘可能遵循 OpenTelemetry
的 HTTP 和 RPC 語義約定。
Category | Usage | Description |
---|---|---|
http | 與 http 操作相關的 Span | |
http.client | ||
http.server | ||
rpc | 與遠端過程呼叫 (RPC) 相關的 Span | |
grpc | gRPC 框架的使用 | |
template | ||
template.init | ||
template.parse | ||
template.render | ||
render | 渲染檢視 | |
serialize | 資料序列化 | |
console | 通過命令列訪問 Web 伺服器(例如 Rails 控制檯) |
Web Frameworks
Category | Usage | Description |
---|---|---|
django | ||
django.middleware | ||
django.view | ||
express | ||
rails | ||
rack |
Database
在可能的情況下,與資料庫相關的 span
應遵循 OpenTelemetry
的 Database 語義約定。
Category | Usage | Description |
---|---|---|
db | 對資料庫的操作 | |
db.connection | ||
db.transaction | ||
db.sql.query | ||
db.query | ||
db.query.compile |
Serverless (FAAS)
Serverless
相關的 span
應儘可能遵循 OpenTelemetry
的 FaaS 語義約定。
Category | Usage | Description |
---|---|---|
faas | serverless function 的呼叫 | |
faas.aws | ||
faas.aws.lambda | ||
faas.aws.request | ||
faas.gcp |
Mobile
Category | Usage | Description |
---|---|---|
app | 關於 mobile app 的資料 | |
app.start | ||
app.start.warm | ||
app.start.cold | ||
ui | 移動/桌面 UI 上的操作 | |
ui.load | ||
ui.action | ||
navigation | 導航到另一個螢幕 | |
file | 對檔案系統的操作 | |
file.read | ||
file.write |
Messages/Queues
Messages/Queues
跨度應儘可能遵循 OpenTelemetry 的 Messaging 語義約定。
Category | Usage | Description |
---|---|---|
topic | ||
topic.send | ||
topic.recieve | ||
topic.process | ||
queue | ||
queue.process | ||
job | ||
job.exec | ||
celery |