使用 OpenTelemetry 構(gòu)建可觀測(cè)性 03 - 導(dǎo)出
上一個(gè)博文中,我提到如何使用 OpenTelemery 的特定語(yǔ)言 API 來收集遙測(cè)數(shù)據(jù),包含手動(dòng)和自動(dòng)的埋點(diǎn)技術(shù),這很重要!但是,收集遙測(cè)數(shù)據(jù)只是解決方案的第一步。
你需要把遙測(cè)數(shù)據(jù)路由轉(zhuǎn)發(fā)到其他地方,同時(shí)添加額外的元數(shù)據(jù)信息。這時(shí)就輪到 SDK 發(fā)揮作用了。
鏈路追蹤生產(chǎn)者( Tracer Provider )
鏈路追蹤生產(chǎn)者是 SDK 中一個(gè)關(guān)鍵概念。用于將通過 API 收集的遙測(cè)數(shù)據(jù)與其他組件聯(lián)系起來。在 Go 語(yǔ)言中,TracerProvider
?對(duì)象只有一個(gè)?Tracer
?方法的接口,方法簽名如下:
Tracer
?方法返回一個(gè)實(shí)現(xiàn)?Tracer
?接口的對(duì)象,這個(gè)接口也只有一個(gè)方法?Start
,其方法簽名如下:
樣例項(xiàng)目中通過鏈路追蹤生產(chǎn)者創(chuàng)建了跨度( span ):
可以發(fā)現(xiàn)通過otel.Tracer
?查找并創(chuàng)建全局的鏈路追蹤生產(chǎn)者最終返回?Tracer
?對(duì)象,需要注意要使用鏈路追蹤生產(chǎn)者,其初始化設(shè)置是不可缺少的。
Note: 在文中提及是獲取‘全局’鏈路追蹤生產(chǎn)者的方法。使用全局鏈路追蹤最簡(jiǎn)單的一種方式就是調(diào)用?otel.Tracer
?的 API 。不過實(shí)際使用中如果上面方案不滿足,還可以通過鏈路追蹤生產(chǎn)者傳遞給消費(fèi)者以替代全局查找的方法。
Note: trace 代表整個(gè)請(qǐng)求的路徑信息、span 代表鏈路中的具體節(jié)點(diǎn)信息
資源( Resource )
鏈路追蹤生產(chǎn)者還需要配置‘資源’對(duì)象,它是元數(shù)據(jù)信息的一部分。資源是遙測(cè)數(shù)據(jù)產(chǎn)生描述過程或者服務(wù)的信息,描述了服務(wù)本身的元數(shù)據(jù),有助于解析遙測(cè)數(shù)據(jù)。
這是樣例項(xiàng)目中購(gòu)物車服務(wù)的‘資源’對(duì)象定義:
資源對(duì)象定義的關(guān)鍵是設(shè)置屬性參數(shù),OpenTelemetry 已經(jīng)定義了一些資源屬性的鍵值對(duì),可以參考這篇文檔?OTel’s 資源語(yǔ)義約定( https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/?)。 例如,你可以通過上面例子看到,如何定義服務(wù)名稱和版本號(hào)信息。但是可能還有更多信息你需要配置,比如服務(wù)自身依賴的資源有哪些;服務(wù)運(yùn)行在云上嗎?需要約定不同的屬性給不同的云服務(wù)供應(yīng)商;服務(wù)運(yùn)行在 Kubernetes 嗎?是的話,這里有份指導(dǎo)手冊(cè)?Kubernetes 的資源語(yǔ)義約定( https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/k8s/?)。
最終樣例項(xiàng)目中, 鏈路追蹤數(shù)據(jù)中 span 都包含這樣的‘資源’數(shù)據(jù):
導(dǎo)出器( Exporter )
既然我們已經(jīng)創(chuàng)建了資源對(duì)象,我們接下來定義一下遙測(cè)數(shù)據(jù)的目的地。
導(dǎo)出器的選擇范圍很廣,可以根據(jù)自己的需求選擇不同的導(dǎo)出器,不過在當(dāng)前項(xiàng)目例子中我使用 OpenTelemetry 控制器(會(huì)在下一篇細(xì)聊),它支持 HTTP 和 gRPC 協(xié)議。我選擇使用 gRPC 協(xié)議和 OTLP 導(dǎo)出器:
Note: 文中例子是演示的程序,使用的非安全的連接方式來獲取數(shù)據(jù),不過生產(chǎn)環(huán)境中你最起碼應(yīng)該要使用帶鑒權(quán)的連接方式。
就導(dǎo)出器而言,有多種方式輸出結(jié)果渠道供你選擇,例如:控制臺(tái)輸出(輸出到 stdout ), Jaeger (直接發(fā)送數(shù)據(jù)給它), Prometheus 等。使用 OTLP 導(dǎo)出器并將數(shù)據(jù)發(fā)送到 OTel Collector 的好處是,您可以創(chuàng)建數(shù)據(jù)副本、并行處理數(shù)據(jù),并擁有更多控制權(quán)(將在下一篇文章中介紹)。
由于使用 OTLP 導(dǎo)出器非常靈活,我們可以根據(jù)需要在 Collector 中使用遙測(cè)數(shù)據(jù)(輸出到 stdout、發(fā)送到 Jaeger 等)。下一篇文章將詳細(xì)介紹這一點(diǎn)!
整合( Tying it all together )
現(xiàn)在我們有了資源(生成遙測(cè)數(shù)據(jù))和導(dǎo)出器(遙測(cè)數(shù)據(jù)的目的地),我們將它們放在一起形成鏈路追蹤生產(chǎn)者:
當(dāng)鏈路追蹤生產(chǎn)者創(chuàng)建后,我們需要將其設(shè)置為全局鏈路追蹤生產(chǎn)者:
接下來我們需要設(shè)置‘傳播’。在后續(xù)博文中,將深入討論傳播和附加數(shù)據(jù)( baggage ,整個(gè)鏈路中傳遞業(yè)務(wù)自定義 KV 屬性),但現(xiàn)在只需要知道‘傳播’可以將 OTel 鏈路追蹤的上下文信息跨多個(gè)服務(wù)進(jìn)行傳遞。讓‘分布式’概念在‘分布式鏈路追蹤’中實(shí)現(xiàn)。
最后,我們需要調(diào)用?TracerProvider.Shutdown
?來清理并關(guān)閉跨度處理器(在例子中,我們使用批量 span 處理器,按批次將 span 數(shù)據(jù)進(jìn)行聚合和批量處理,然后將完整的批處理結(jié)果發(fā)送給導(dǎo)出器):
Note: 為了可靠性和可讀性,僅通過調(diào)用?defer tp.Shutdown(context.Background())?是不夠的,需要處理函數(shù)返回的一些錯(cuò)誤。
鏈路追蹤生產(chǎn)者 Python 版( Python tracer provider )
樣例項(xiàng)目中大部分服務(wù)都用 Go 語(yǔ)言來編寫,用 Python 寫了一個(gè)服務(wù)(定價(jià)服務(wù))。為了完整起見,以下是如何在 Python 中創(chuàng)建和設(shè)置類似的鏈路追蹤生產(chǎn)者的例子:
其中資源、span 處理器和設(shè)置全局鏈路追蹤生產(chǎn)者的實(shí)現(xiàn)與 Go 描述相同。
總結(jié)
很棒前進(jìn)了一步!按照上面步驟實(shí)現(xiàn)了,通過 API 獲取了遙測(cè)數(shù)據(jù),并將其從當(dāng)前組件中被發(fā)送到一個(gè)導(dǎo)出器,并向其中添加了一些元數(shù)據(jù)(資源)!接下來我們將了解如何使用 OpenTelemetry 收集器來處理這來數(shù)據(jù)。
本文翻譯自:https://trstringer.com/otel-part3-export/
擴(kuò)展閱讀:
方法論:面向故障處理的可觀測(cè)性體系建設(shè)(?https://flashcat.cloud/blog/construction-of-observability-system-for-fault-processing/?)
白皮書:事件 OnCall 中心建設(shè)方法(?https://download.flashcat.cloud/flashduty-white-paper-v1.pdf?)
好工具:FlashDuty - 一站式告警處理平臺(tái):告警降噪、排班OnCall ( https://flashcat.cloud/product/flashduty/?)