版本 1.0html
The OpenTracing Semantic Specificationgit
這是一份」正式」的OpenTracing語義規範文檔。因爲OpenTracing是跨語言的,本文檔會盡可能避免提到特定語言相關的概念。也就是說,咱們認爲全部語言都具備相似」接口」這樣的概念,並提供相關的功能。github
OpenTracing採用了 主版本號.次版本號
形式的版本號,可是沒有 .修訂號
。當對規範進行向後不兼容的更改時,主版本增長。次版本的增長則用於用於不間斷更改,如引入新的標準標記,日誌字段或SpanContext引用類型。(你能夠在這個Issue specification#2 中讀到更多有關此版本控制方案的信息)編程
OpenTracing中的Traces由其Span隱式定義。Trace可被認爲是由一組Span定義的有向無環圖(DAG),在Span之間的被稱爲References。網絡
如下是一個由8個Span構成的Trace的例子:併發
一個Trace中Span間的因果關係 [Span A] ←←←(the root span) | +------+------+ | | [Span B] [Span C] ←←←(Span C之於Span A的關係是 `ChildOf` ) | | [Span D] +---+-------+ | | [Span E] [Span F] >>> [Span G] >>> [Span H] ↑ ↑ ↑ (Span G `FollowsFrom` Span F)
有時用時間軸來顯示Traces更容易,以下圖所示:編程語言
一個Trace中Span間的時間關係 ––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time [Span A···················································] [Span B··············································] [Span D··········································] [Span C········································] [Span E·······] [Span F··] [Span G··] [Span H··]
每一個Span封裝了以下狀態:分佈式
操做名稱函數
開始時間戳工具
結束時間戳
一組零或多個鍵:值結構的Span標籤(Tags)。鍵必須是字符串。值能夠是字符串,布爾或數值類型.
一組零或多個Span日誌(Logs),其中每一個都是一個鍵:值映射並與一個時間戳配對。鍵必須是字符串,值能夠是任何類型。 並不是全部的OpenTracing實現都必須支持每種值類型。
一個SpanContext(見下文)
零或多個因果相關的Span間的References (經過那些相關的Span的SpanContext)
每一個SpanContext封裝了以下狀態:
任何須要跟跨進程Span關聯的,依賴於OpenTracing實現的狀態(例如Trace和Span的id)
鍵:值結構的跨進程的Baggage Items
一個Span可引用零或多個因果相關的SpanContext。OpenTracing目前定義了兩種類型的Reference: ChildOf
和 FollowsFrom
。這兩種Reference類型都對父子Span間的因果關係進行了建模。將來,OpenTracing可能會爲不具因果關係的Span提供不一樣類型的Reference (例如批量的Span,卡在隊列中的Span等)。
ChildOf
reference: 一個Span能夠是另外一個Span的子Span。在 ChildOf
引用中,父Span在某種程度上取決於子Span。下列狀況會構成 ChildOf
關係:
在一個RPC中,表明服務端的Span可做爲 ChildOf
表明客戶端的Span
在一個持久化進程中,表明SQL插入的Span可做爲 ChildOf
表明ORM save方法的Span
多個併發(多是分佈式)執行任務的Span可能分別各自爲 Childof
一個合併了多個子Span結果的父Span
下列這些都是有效的具備 ChildOf
關係的時序圖
[-Parent Span---------] [-Child Span----] [-Parent Span--------------] [-Child Span A----] [-Child Span B----] [-Child Span C----] [-Child Span D---------------] [-Child Span E----]
FollowsFrom
reference: 有些父Span不依賴於任何子Span的結果。這種狀況下,咱們僅認爲子Span在因果上 FollowsFrom
父Span。有許多不一樣的 FollowsFrom
引用子類別,在OpenTracing的將來版本中,它們可能會被更正式地區分。
下列這些都是有效的具備 FollowsFrom
關係的時序圖
[-Parent Span-] [-Child Span-] [-Parent Span--] [-Child Span-] [-Parent Span-] [-Child Span-]
OpenTracing規範中有三種相互關聯的關鍵類型 Tracer
,Span
,and SpanContext
。接下來,咱們來看一下各類類型的行爲; 簡單來講,每種行爲分別在編程語言中對應爲一個」方法」,儘管實際上多是一組重載方法。
當咱們討論「可選」參數時,應當清楚,不一樣的語言有不一樣的方式來解釋這個概念。好比說,在Go語言中咱們會使用」functional Options」這個術語,而在Java中咱們會使用builder模式。
Tracer
Tracer
接口創造 Span
而且可以跨進程地 Inject
(序列化)和 Extract
(反序列化)。嚴格來講,它應具備如下能力:
Span
必須參數
操做名稱,一我的工可讀的字符串,它簡潔地表示由Span完成的工做 (例如,RPC方法名稱、函數名稱或一個較大的計算任務中的階段的名稱)。操做名稱應該用泛化的字符串形式標識出一個Span實例. 也就是說,get_user
比 get_user/314159
好。
好比說這裏有幾個操做名稱,用於獲得一個虛構的帳戶信息:
操做名稱 | 建議 |
---|---|
get |
太寬泛 |
get_account/792 |
太具體 |
get_account |
剛恰好,account_id=792 可做爲一個合適的 Span 標籤 |
可選參數
零或多個與 SpanContext
相關的references,儘量包括 ChildOf
和 FollowFrom
引用類型的信息
開始時間戳,若是沒有的話,默認使用現實時間(walltime)
零或多個標籤
返回值是一個剛剛啓動的 Span
實例
SpanContext
到載體中必須參數
SpanContext
實例
格式描述符(format descriptor)(一般但不必定是字符串常量),告訴Tracer的實現如何在載體對象中對SpanContext進行編碼
載體(carrier),其類型由格式描述符指定。Tracer的實現將根據格式描述對此載體對象中的SpanContext進行編碼
SpanContext
必須參數
格式描述符(format descriptor),告訴Tracer的實現如何在載體對象中對SpanContext進行解碼
載體,其類型由格式描述符指定。 Tracer的實現將根據格式描述對此載體對象中的SpanContext進行解碼
返回值是一個SpanContext實例,適合做爲經過Tracer啓動Span時的reference
Injection和Extraction都依賴於一個可擴展的格式描述符參數,其指定了相關聯的」載體」類型以及 SpanContext
是如何被編碼的。Tracer實現必須支持下列全部格式。
文本映射(Text Map): 任意的無字符編碼限制的string-string型鍵值結構
HTTP Headers: string-string型的鍵值結構在HTTP headers( RFC 7230 )中也適用。在實操中,因爲HTTP header很容易被各類不一樣的方式處理, 強烈建議在Tracer的實現中使用有限的鍵空間和保守的轉意值
二進制: 表明了 SpanContext
的任意二進制數據
Span
除了獲取 Span
的 SpanContext
的方法以外,下面任何方法都不能在 Span
完成後被調用。
Span
的 SpanContext
無需參數。
返回值是 Span
的 SpanContext
。返回值甚至可能在 Span
結束後被使用。
必須參數
新的操做名,當 Span
啓動時取代舊內容
Span
可選參數
顯式地添加Span的結束時間戳,若是沒有這個參數則會隱式的添加現實時間(walltime)
除了獲取Span的SpanContext的方法以外,任何Span對象的方法都不能在其完成後被調用。
Span
標籤必須參數
標籤的鍵,必須是字符串
標籤的值,必須是字符串,布爾值,數值類型其中之一
注意OpenTracing項目文檔中已經爲一些」標準標籤」規定了語義。
記錄(Log)
結構化的數據必須參數
一到多個鍵值對,鍵必須是字符串,值能夠是任意類型。有些OpenTracing的實現能夠處理更多的日誌的值。
可選參數
顯式時間戳。該參數必須落在當前Span的開始與結束時間戳之間。
注意OpenTracing項目文檔中已經爲一些「日誌的標準鍵「 規定了語義。
Baggage item是對應於某個 Span
及其 SpanContext
,以及全部直接或間接引用自本地(local) Span
的 Span
的鍵值對。也就是說,baggage items是與其trace一塊兒傳播的。
Baggage item爲全棧式的OpenTracing集成提供了強大的功能(好比在移動App上使用時,它能夠一路追蹤數據直至儲存系統的深度),不過使用這些功能時要小心。
每一個鍵值都會被拷貝到每個本地(local)及遠程的子Span,這可能致使巨大的網絡和CPU開銷。
必須參數
baggage鍵,字符串
baggage值,字符串
必須參數
baggage鍵,字符串
返回值是對應的baggage值,或是一個表示沒有baggage值的一個量。
SpanContext
在通常所指的OpenTracing層面上,SpanContext
更像是一個概念而不是一種實用功能。也就是說,這對OpenTracing的實現來講提供一層薄的接口是相當重要的。當啓動一個 Span
或者注入/提取(injecting/extracting) trace時,多數OpenTracing用戶僅經過reference與 SpanContext
進行交互。
在OpenTracing中,SpanContext
被強制設定爲不可變的(immutable),以應對在 Span
結束時和引用(reference)時產生的複雜的生命週期問題。
不一樣語言對此有不一樣的建模方式,不過給出一個 SpanContext
實例,語義上仍是應該能讓調用者在短期內遍歷baggage items。
NoopTracer
全部語言的OpenTracing API必須提供某種 NoopTracer
實現,可用做標記控制(flag-control)或者進行一些用於測試的無害注入等。某些狀況下(好比Java),NoopTracer
可能在它本身的製品包(packaging artifact)中。
有些語言提供了在單進程中用來傳遞活動的 Span
和 SpanContext
的工具。好比,opentracing-go
提供了在Go的 context.Context
機制中,用來set和get活動 Span
的幫助函數(helpers)。