最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

OpenTelemetry-go的SDK使用方法詳解

 更新時間:2022年09月23日 15:25:41   作者:迷茫路人  
這篇文章主要介紹了OpenTelemetry-go的SDK使用方法,OpenTelemetry幫我們實現(xiàn)了相應(yīng)語言的SDK,所以我們只需要進(jìn)行調(diào)用即可,本文根據(jù)官方文檔實例講解,需要的朋友可以參考下

2019年5月,OpenCensus 和 OpenTracing形成了 OpenTelemetry(簡稱 OTel)

也就是說,我們在使用鏈路追蹤SDK的時候就需要使用OpenTelemetry的新規(guī)范.OpenTelemetry幫我們實現(xiàn)了相應(yīng)語言的SDK,所以我們只需要進(jìn)行調(diào)用即可.
接下來,我們開始對go所對應(yīng)的SDK進(jìn)行使用.

本文主要根據(jù)官方文檔實例進(jìn)行講解.

例子

本文簡化了官方的例子,每個地方都已注釋完畢! 例子使用jaeger作為鏈路追蹤服務(wù)器.

首先我們先引入它的包.

# 安裝核心模塊
go get go.opentelemetry.io/otel \
       go.opentelemetry.io/otel/trace
# 安裝導(dǎo)出器,這里導(dǎo)出器使用的是stdout
go get go.opentelemetry.io/otel/sdk \
         go.opentelemetry.io/otel/exporters/stdout/stdouttrace
# 因為我們需要使用jaeger所以要導(dǎo)入jaeger導(dǎo)出器
go get -u go.opentelemetry.io/otel/exporters/jaeger

當(dāng)我們導(dǎo)入上面的包之后,就可以運行例子了.

package main
import (
	"context"
	"fmt"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/sdk/resource"
	"go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
)
// 計算斐波那契隊列
func Fibonacci(n uint) (uint64, error) {
	if n <= 1 {
		return uint64(n), nil
	}

	var n2, n1 uint64 = 0, 1
	for i := uint(2); i < n; i++ {
		n2, n1 = n1, n1+n2
	}

	return n2 + n1, nil
}
// 這里模擬服務(wù)之間的掉用的效果.
func Run(ctx context.Context) {
	_, span := otel.Tracer("nihao").Start(ctx, "two")
	defer span.End()
	fibonacci, err := Fibonacci(20)
	if err != nil {
		return
	}
	fmt.Println(fibonacci)
}
// newExporter returns a console exporter.
// 創(chuàng)建導(dǎo)出器,對于鏈路追蹤服務(wù)器的選擇就是在這里配置
// 下面是基于jaeger的導(dǎo)出器.
// 這里需要注意,在使用jaeger導(dǎo)出器的時候傳輸格式是jaeger.thrift over HTTP
// 所以在配置url時請使用14268端口 與/api/traces
func newExporter(url string) (*jaeger.Exporter, error) {
	return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
}

// 資源是一種特殊類型的屬性,適用于進(jìn)程生成的所有跨度。這些應(yīng)該用于表示有關(guān)非臨時進(jìn)程的底層元數(shù)據(jù)
// 例如,進(jìn)程的主機(jī)名或其實例 ID
func newResource() *resource.Resource {
	r, _ := resource.Merge(
		resource.Default(),
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("fib"),
			semconv.ServiceVersionKey.String("v0.1.0"),
			attribute.String("environment", "demo"),
		),
	)
	return r
}

// 主函數(shù)
func main() {
	url := "http://collector.tl.com:31498/api/traces"
	// 創(chuàng)建導(dǎo)出器
	exp, _ := newExporter(url)
	// 創(chuàng)建鏈路生成器,這里將導(dǎo)出器與資源信息配置進(jìn)去.
	tp := trace.NewTracerProvider(
		trace.WithBatcher(exp),
		trace.WithResource(newResource()),
	)
	// 結(jié)束時關(guān)閉鏈路生成器
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			fmt.Println(err)
		}
	}()

	// 將創(chuàng)建的生成器設(shè)置為全局變量.
	// 這樣直接使用otel.Tracer就可以創(chuàng)建鏈路.
	// 否則 就要使用 tp.Tracer的形式創(chuàng)建鏈路.
	otel.SetTracerProvider(tp)
	newCtx, span := otel.Tracer("nihao").Start(context.Background(), "one")
	Run(newCtx)
	span.End()
}

原理

運行成功了,那么它的底層原理是怎么實現(xiàn)的,每個組件是怎么組織的?
這里我將根據(jù)上面的例子畫一張流程圖來進(jìn)行說明.

通過上面的圖我們可以知道,跨度之間的傳輸使用的是Context 來實現(xiàn)的.
使用span.end()就是將當(dāng)前跨度信息發(fā)送給鏈路追蹤服務(wù)器.

方法使用

接下來讓我們根據(jù)上面的例子講解一下他們每個方法的使用方式與配置吧!

newExporter

它的作用是創(chuàng)建一個導(dǎo)出器
在里面有兩種配置

// 配置jaeger服務(wù)器
jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))
// 參數(shù)是一個options ...CollectorEndpointOption所以讓我們看一下都有哪些配置
jaeger.WithEndpoint(endpoint string) // 配置服務(wù)器地址
jaeger.WithUsername(username string) // 配置用戶名
jaeger.WithPassword(password string) // 配置密碼
jaeger.WithHTTPClient(client *http.Client) //設(shè)置用于發(fā)送給jeager服務(wù)器所用到的client,有默認(rèn).這里可以設(shè)置

// 配置jaeger-agent 代理地址
jaeger.WithAgentEndpoint()
// 參數(shù)是options ...AgentEndpointOption
jaeger.WithAgentHost(host string) // 設(shè)置代理host
jaeger.WithAgentPort(port string) // 設(shè)置代理端口
jaeger.WithLogger(logger *log.Logger) // 設(shè)置日志系統(tǒng)
jaeger.WithDisableAttemptReconnecting() // 設(shè)置禁止重新連接UDP
jaeger.WithAttemptReconnectingInterval(interval time.Duration) // 設(shè)置代理解析jaeger服務(wù)器之間的時間間隔
jaeger.WithMaxPacketSize(size int) // 設(shè)置UDP傳輸?shù)淖畲蟀?/pre>

無論是使用agent還是Collector,導(dǎo)出器都 使用batchUploader,也就是批量上傳策略.

newResource

存在于每個span中,在jaegerUI上顯示的是tag下面的Process
它有默認(rèn)設(shè)置,也可以自定義,下面讓我們看一下具體使用

// merge 只是合并下面的兩組資源.
r, _ := resource.Merge(
        // 設(shè)置默認(rèn)的資源. 進(jìn)程id等
		resource.Default(),
        // 設(shè)置自定義屬性
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("fib"),
			semconv.ServiceVersionKey.String("v0.1.0"),
            // 我們可以使用該方法,來進(jìn)行添加自定義屬性
			attribute.String("environment", "demo"),
		),
	)

這里并不強(qiáng)制使用resource.NewWithAttributes,只要返回值是 resource.Resource 即可

trace.NewTracerProvider

創(chuàng)建一個鏈路生成器,我們主要使用它來進(jìn)行鏈路追蹤

	// 創(chuàng)建生成器,這里配置了資源與 導(dǎo)出器.
tp := trace.NewTracerProvider(
		trace.WithBatcher(exp),
		trace.WithResource(newResource()),
	)
// 下面讓我們看一下它都有哪些配置
// 這里創(chuàng)建的是批量處理導(dǎo)出器,也就是我們常用的
WithBatcher(e SpanExporter, opts ...BatchSpanProcessorOption)
// 這里可以添加別的導(dǎo)出器,也就是說可以同時發(fā)送給jaeger與zipkin
WithSpanProcessor(sp SpanProcessor)
// 配置資源
WithResource(r *resource.Resource)
// Tracers id與span id生成器,默認(rèn)為隨機(jī)數(shù)
WithIDGenerator(g IDGenerator)
// 設(shè)置采樣數(shù)
WithSampler(s Sampler)
// 設(shè)置屬性,資源的數(shù)量
WithSpanLimits(sl SpanLimits)
WithRawSpanLimits(limits SpanLimits)

這里重點講解一下SpanProcessor.
SpanProcessor是一個導(dǎo)出器策略,存儲著如何發(fā)送span到鏈路服務(wù)器上,有兩種方式批處理和立即發(fā)送。
我們上面說的WithCollectorEndpoint 與 WithAgentEndpoint 都是創(chuàng)建的BatchSpanProcessor 也就是批處理導(dǎo)出器策略.還存在一個SpanProcessor為simpleSpanProcessor,這個就是立刻發(fā)送,沒有批處理操作.
我們添加其他導(dǎo)出器以及策略的方式:
如果使用BatchSpanProcessor 那么在創(chuàng)建TracerProvider時的傳參使用trace.WithBatcher即可
如果想自定義,則使用WithSpanProcessor
比如使用simpleSpanProcessor,則設(shè)置為 WithSpanProcessor(jaeger.NewSimpleSpanProcessor(exporter SpanExporter))

沒錯,想要添加一個導(dǎo)出器就需要配置導(dǎo)出策略。所以導(dǎo)出器與導(dǎo)出策略時綁定的。

otel

otel是一個全局配置組件,我們可以將生成器設(shè)置為全局屬性,方便調(diào)用。

otel.SetTracerProvider(tp)

注意

具體的span使用請訪問
下文都是拷貝官網(wǎng).

獲取當(dāng)前跨度

通過上面我們知道,對當(dāng)前跨度的操作是使用span就可以了,但是在日常過程中我們不能傳輸兩個值一個Context和span(通常只傳輸Context),所以可以使用Context逆向解析出當(dāng)前的span.

ctx := context.TODO()
span := trace.SpanFromContext(ctx)

:::success
下面所有設(shè)置都會在每個span的log中展示出來,只是為了更能標(biāo)識信息,沒有實質(zhì)性的用處.(比如設(shè)置even,并不是運行這個事件,只是輸出一個key為even value 為msg的信息)
:::

設(shè)置span狀態(tài)

span.SetStatus(codes.Error, "operationThatCouldFail failed")

設(shè)置span屬性

span.SetAttributes(attribute.Bool("isTrue", true), attribute.String("stringAttr", "hi!"))

記錄錯誤

span.RecordError(err)

設(shè)置活動

span.AddEvent("Acquiring lock")

tp.Shutdown

注意在使用完后已經(jīng)要調(diào)用Shutdown,它的功能是關(guān)閉客戶端與鏈路服務(wù)器之間的連接,也就是我們?yōu)閮蓚€服務(wù)建立連接后為了防止資源浪費所以會調(diào)用 con.close() 即使關(guān)閉.

defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			fmt.Println(err)
		}
	}()

到此這篇關(guān)于OpenTelemetry-go的SDK使用方法的文章就介紹到這了,更多相關(guān)OpenTelemetry-go的sdk內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Go語言微服務(wù)開發(fā)框架之Go chassis

    詳解Go語言微服務(wù)開發(fā)框架之Go chassis

    分布式系統(tǒng)中每個進(jìn)程的動態(tài)配置管理及運行時熱加載就成為了一個亟待解決的問題。go chassis汲取了netflix的archaius框架經(jīng)驗,并做出來自己的創(chuàng)新特性。
    2021-05-05
  • 安裝GoLang環(huán)境和開發(fā)工具的圖文教程

    安裝GoLang環(huán)境和開發(fā)工具的圖文教程

    Go是一門由Google開發(fā)的編程語言,GoLand的安裝非常簡單,本文主要介紹了安裝GoLang環(huán)境和開發(fā)工具的圖文教程,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Golang?Time包與日期函數(shù)的用法詳解

    Golang?Time包與日期函數(shù)的用法詳解

    在golang中,time包提供了時間的顯示和測量用的函數(shù),下面小編就來和大家詳細(xì)聊聊Golang中Time包與日期函數(shù)的具體用法,快跟隨小編一起學(xué)習(xí)一下吧
    2023-07-07
  • 使用golang-unsafe包的注意事項及說明

    使用golang-unsafe包的注意事項及說明

    這篇文章主要介紹了使用golang-unsafe包的注意事項及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • golang?手寫貪吃蛇示例實現(xiàn)

    golang?手寫貪吃蛇示例實現(xiàn)

    這篇文章主要為大家介紹了golang?手寫貪吃蛇示例實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語言實現(xiàn)的web爬蟲實例

    Go語言實現(xiàn)的web爬蟲實例

    這篇文章主要介紹了Go語言實現(xiàn)的web爬蟲,實例分析了web爬蟲的原理與Go語言的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Golang實現(xiàn)單元測試中的邏輯層

    Golang實現(xiàn)單元測試中的邏輯層

    前面我們完成了最麻煩的數(shù)據(jù)層的單元測試,今天我們來看看單元測試中最容易做的一層,數(shù)據(jù)邏輯層,也就是我們通常說的 service 或者 biz 等
    2023-03-03
  • go語言實現(xiàn)全排列的示例代碼

    go語言實現(xiàn)全排列的示例代碼

    本文主要介紹了go語言實現(xiàn)全排列的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Go語言基礎(chǔ)switch條件語句基本用法及示例詳解

    Go語言基礎(chǔ)switch條件語句基本用法及示例詳解

    這篇文章主要為大家介紹了Go語言基礎(chǔ)switch條件語句基本用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Golang函數(shù)重試機(jī)制實現(xiàn)代碼

    Golang函數(shù)重試機(jī)制實現(xiàn)代碼

    在編寫應(yīng)用程序時,有時候會遇到一些短暫的錯誤,例如網(wǎng)絡(luò)請求、服務(wù)鏈接終端失敗等,這些錯誤可能導(dǎo)致函數(shù)執(zhí)行失敗,這篇文章主要介紹了Golang函數(shù)重試機(jī)制實現(xiàn)代碼,需要的朋友可以參考下
    2024-04-04

最新評論

江门市| 武宣县| 大港区| 福清市| 麻阳| 高密市| 南江县| 弋阳县| 绍兴市| 岑巩县| 衡阳市| 玛曲县| 邵阳市| 泸州市| 徐汇区| 兴文县| 华亭县| 宁强县| 遵化市| 衡阳县| 蒲江县| 囊谦县| 金乡县| 喀喇| 基隆市| 平安县| 崇礼县| 普兰店市| 渝北区| 静海县| 台山市| 老河口市| 筠连县| 文成县| 榆社县| 尼勒克县| 红河县| 荥阳市| 宁国市| 巴里| 嵩明县|