欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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使用協(xié)程批量獲取數(shù)據(jù)加快接口返回速度

    Go使用協(xié)程批量獲取數(shù)據(jù)加快接口返回速度

    這篇文章主要介紹了Go使用協(xié)程批量獲取數(shù)據(jù)加快接口返回速度,使用Go語言后,可以并發(fā)獲取,極大提升效率,需要的朋友可以參考下
    2023-02-02
  • 使用GORM將PostgreSQL集成到Go框架中

    使用GORM將PostgreSQL集成到Go框架中

    在go中集成postgresql需使用gorm orm,步驟如下:安裝go和postgresql,安裝 gorm:go get -u gorm.io/gorm,配置數(shù)據(jù)庫連接字符串,定義模型類,遷移數(shù)據(jù)庫架構(gòu),使用 gorm 進(jìn)行增刪改查操作,本指南將介紹如何使用 GORM(一個廣受歡迎的 ORM),將PostgreSQL集成到你的Go應(yīng)用中
    2024-08-08
  • go語言csrf庫使用實現(xiàn)原理示例解析

    go語言csrf庫使用實現(xiàn)原理示例解析

    這篇文章主要為大家介紹了go語言csrf庫使用實現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • golang的os包用法詳解

    golang的os包用法詳解

    Go語言的 os 包中提供了操作系統(tǒng)函數(shù)的接口,是一個比較重要的包。顧名思義,os 包的作用主要是在服務(wù)器上進(jìn)行系統(tǒng)的基本操作,本文將詳細(xì)介紹了golang的os包用法,需要的朋友可以參考下
    2023-05-05
  • Golang利用位運算實現(xiàn)為程序加速

    Golang利用位運算實現(xiàn)為程序加速

    這篇文章主要為大家詳細(xì)介紹了如何在Golang中利用位運算實現(xiàn)為程序加速功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-08-08
  • Goland配置leetcode的實現(xiàn)示例

    Goland配置leetcode的實現(xiàn)示例

    本文主要介紹了Goland配置leetcode的實現(xiàn)示例,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • golang?pprof?監(jiān)控goroutine?thread統(tǒng)計原理詳解

    golang?pprof?監(jiān)控goroutine?thread統(tǒng)計原理詳解

    這篇文章主要為大家介紹了golang?pprof?監(jiān)控goroutine?thread統(tǒng)計原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 一文理解Go 中的可尋址和不可尋址

    一文理解Go 中的可尋址和不可尋址

    如果字典的元素不存在,則返回零值,而零值是不可變對象,如果能尋址問題就大了。而如果字典的元素存在,考慮到 Go 中 map 實現(xiàn)中元素的地址是變化的,這意味著尋址的結(jié)果也是無意義的。下面我們就圍繞這個話題寫一篇文章吧,需要的朋友可以參考一下
    2021-10-10
  • golang爬蟲colly?發(fā)送post請求

    golang爬蟲colly?發(fā)送post請求

    本文主要介紹了golang爬蟲colly?發(fā)送post請求實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Go語言的反射機(jī)制詳解

    Go語言的反射機(jī)制詳解

    本文詳細(xì)講解了Go語言的反射機(jī)制,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07

最新評論