為什麼要使用?
這邊我直接點出我個人的觀點,歡迎大家來探討到底需不需要導入 tracing 的概念在專案中。
就我個人的理解導入 tracing 有幾個好處,能提供系統運作時有更全面的理解與追縱,包括延遲,錯誤以及效能等問題,我們可以透過 tracing 查看整個系統或是單個應用程式是如何處理某一項業務操作 並且追蹤此項操作的流程與相關訊息。
這樣帶來了什麼好處?
如果可以透過圖表等方式顯示我們跟蹤的結果,可以加速後續維運人員排除故障的速度並且可以幫助開發者找到效能問題的癥結點,此外我們還可以看到一條業務邏輯實際的流向是如何被處理的。
那什麼是Opentracing
再談談 Opentracing 之前我們可以將時間回推倒90年代,當時 Google 發表了一篇關於分散是追蹤的論文“Dapper, a Large-Scale Distributed Systems Tracing Infrastructure”,除了該篇論文外 Google 還發表了另外一篇分散式追蹤的的問題所在“Uncertainty in Aggregate Estimates from Sampled Distributed Traces”,兩篇論文都非常的精采說明了為什麼需要做分散式追蹤以及追蹤帶來的效益已提以及追蹤帶來的效益與其困難點。
隨後各家廠商跟著這幾篇論文的引導開發出一系列相關的工具例如, Dapper 、 Zipkin 、 Appdash 等等,越來越多廠商到了戰場上爭奪這一塊 tracing 的大餅,不過就使用者而言就相當的頭痛了,對於各廠商提供的 API 與系統支援度都不相同的情況之下,使用者幾乎沒有辦法無痛得轉移所使用的 tracing System。
下一個時代來臨必須要有人統一群雄打造一個輕量級且標準化的中介層統一上下層之間的隔閡, CNCF 底下的 OpenTracing 願景為提供一個標準的 tracing API 所有使用者只要在乎 OpenTracing tracing 所提供的 API ,不需要再了解各家廠商如 Zipkin 、 Appdash 的流程,這點我認為他跟 Kubernetes 的 CNI 、 CRI 、 CSI有異曲同工之妙。

名词解释
在了解 Opentracing 的由來之後,現在來介紹他的架構與相關的名詞,這有助於我們後續開發上的 API 使用。
Trace
一個 trace 在 Opentracing 代表一個事件在系統的執行過程,我們可以從圖中看到藍色的代表一個事件在 Opentracing 稱為一個 trace ,底下經過紅色綠色以及灰色的處理。
比較學術的說法唯有向無環圖Directed Acyclic Graph ( DAG ),有興趣的可以去查查這是什麼。

Span
span 代表在 Opentracing 中各個工作單元。一個 span 可以包含其他 span 的 reference ,如此一來可以形成一個父子關係圖,進而形成一個完整的 trace 。
其中 span 會攜帶一些資訊方便使用者閱讀例如:
- reference
- span 名稱
- span 開始與結束時間
- tag
- log
- span Context
- baggage Items

ChildOf
先來看看流程結構時序圖,Childof 我會歸類成父節點依賴子節點的結果。例如 Server Span 透過 RPC等方式 去叫了 register Span , register Span 處理了一些資料又去呼叫 SQL Span 做 insert 的動作,SQL Span 對 SQL 存入資料後會返回給 register Span 回報 insert 動作成功,接著 register Span 又會返回給 Server Span 註冊成功的消息。
這種父節點依賴子節點的行為稱為ChildOf。
[-Parent Server Span--------------]
[-Child register Span A----]
[-Child Span B----]
FollowsFrom
先來看看流程結構時序圖,父節點不依賴任何子節點的結果我把他歸類為 FollowsFrom ,例如我發送一條訊息,訊息是否成功被處理與發訊息的事件沒有關聯,這時就稱為 FollowsFrom 。
[-Parent Span-] [-Child Span-]
Span-tag
在 OpenTracing 的規範之下,每一個 span 都可以有 tag 屬性以 key-value 的形式出現。 tag 我們可以理解成某一種屬性例如圖中的error tag ,我們可以利用這格屬性過濾掉error =false 的span,方便我們查詢我追蹤。

Span-log
除了 tag 之外 Opentracing 還規範了 log ,開發者可以在 span 中加入 log ,他以以 key-value 的形式出現,方便開發者或是維運人員快速地檢視該 span 執行的相關訊息。如圖所示可以看到在 external service api 中的 log event 顯示time out 我們可以很快瞭解在執行這個操作的時候他的撞快為何。

Span Context
我認為這個比較難解釋,可以參考著官方的說明對照著看,簡單的說就是span會傳遞 context 資訊給下一個 span ,例如 spanID 、traceID等。
The SpanContext carries data across process boundaries. Specifically, it has two major components:
An implementation-dependent state to refer to the distinct span within a trace
i.e., the implementing Tracer’s definition of spanID and traceID
Any Baggage Items
These are key:value pairs that cross process-boundaries.
These may be useful to have some data available for access throughout the trace.
Baggage Items
從字面上來看 baggage 就是行李的意思,一個 trace 開始到結束,可能會從某一個 span 攜帶行李到下一個 span 進行處理,不過這裡有一個非常重要的點就是行李在整個 trace 的過程都不會被丟棄,直到 trace 結束為止。
從範例來看App A 是一個 span ,攜帶了一些資料到如ot-baggage-environment:production 到 APP B 如果後面還有 APP C 、APP D,這一個資料會傳到整個trace結束為止。

小結
上面我們討論了 Opentracing 的前世今生,為什麼要有 tracing 以及相關的論文。同時針對 Opentracing 會出現的名詞做一個初步的解說,可以以幫助我們後續再使用 Opentracing 提供的 API 時更能了解他所代表的意義以及正確的使用姿勢。下一篇我會續繼分享Opentracing with jaeger 的用法。