1. 為 Go 應(yīng)用添加 Prometheus 監(jiān)控指標(biāo)

        共 12433字,需瀏覽 25分鐘

         ·

        2021-10-09 18:05

        前面我們了解了如何儀表化應(yīng)用,接下來(lái)我們將學(xué)習(xí)使用 Prometheus 的 Go 客戶端庫(kù)來(lái)為一個(gè) Go 應(yīng)用程序添加和暴露監(jiān)控指標(biāo)。

        創(chuàng)建應(yīng)用

        我們首先從一個(gè)最簡(jiǎn)單的 Go 應(yīng)用程序開(kāi)始,在端口 8080 的 /metrics 端點(diǎn)上暴露客戶端庫(kù)的默認(rèn)注冊(cè)表,暫時(shí)還沒(méi)有跟蹤任何其他自定義的監(jiān)控指標(biāo)。

        先創(chuàng)建一個(gè)名為 instrument-demo 的目錄,在該目錄下面初始化項(xiàng)目:

        ????mkdir?instrument-demo?&&?cd?instrument-demo
        ????go?mod?init?github.com/cnych/instrument-demo

        上面的命令會(huì)在 instrument-demo 目錄下面生成一個(gè) go.mod 文件,在同目錄下面新建一個(gè) main.go 的入口文件,內(nèi)容如下所示:

        package?main

        import?(
        ?"net/http"

        ?"github.com/prometheus/client_golang/prometheus/promhttp"
        )

        func?main()?{
        ????//?Serve?the?default?Prometheus?metrics?registry?over?HTTP?on?/metrics.
        ?http.Handle("/metrics",?promhttp.Handler())
        ?http.ListenAndServe(":8080",?nil)
        }

        然后執(zhí)行下面的命令下載 Prometheus 客戶端庫(kù)依賴(lài):

        ????export?GOPROXY="https://goproxy.cn"
        ????go?mod?tidy
        go:?finding?module?for?package?github.com/prometheus/client_golang/prometheus/promhttp
        go:?found?github.com/prometheus/client_golang/prometheus/promhttp?in?github.com/prometheus/client_golang?v1.11.0
        go:?downloading?google.golang.org/protobuf?v1.26.0-rc.1

        然后直接執(zhí)行 go run 命令啟動(dòng)服務(wù):

        ????go?run?main.go

        然后我們可以在瀏覽器中訪問(wèn) http://localhost:8080/metrics 來(lái)獲得默認(rèn)的監(jiān)控指標(biāo)數(shù)據(jù):

        #?HELP?go_gc_duration_seconds?A?summary?of?the?pause?duration?of?garbage?collection?cycles.
        #?TYPE?go_gc_duration_seconds?summary
        go_gc_duration_seconds{quantile="0"}?0
        go_gc_duration_seconds{quantile="0.25"}?0
        go_gc_duration_seconds{quantile="0.5"}?0
        go_gc_duration_seconds{quantile="0.75"}?0
        go_gc_duration_seconds{quantile="1"}?0
        go_gc_duration_seconds_sum?0
        go_gc_duration_seconds_count?0
        #?HELP?go_goroutines?Number?of?goroutines?that?currently?exist.
        #?TYPE?go_goroutines?gauge
        go_goroutines?6
        ......
        #?HELP?go_threads?Number?of?OS?threads?created.
        #?TYPE?go_threads?gauge
        go_threads?8
        #?HELP?promhttp_metric_handler_requests_in_flight?Current?number?of?scrapes?being?served.
        #?TYPE?promhttp_metric_handler_requests_in_flight?gauge
        promhttp_metric_handler_requests_in_flight?1
        #?HELP?promhttp_metric_handler_requests_total?Total?number?of?scrapes?by?HTTP?status?code.
        #?TYPE?promhttp_metric_handler_requests_total?counter
        promhttp_metric_handler_requests_total{code="200"}?1
        promhttp_metric_handler_requests_total{code="500"}?0
        promhttp_metric_handler_requests_total{code="503"}?0

        我們并沒(méi)有在代碼中添加什么業(yè)務(wù)邏輯,但是可以看到依然有一些指標(biāo)數(shù)據(jù)輸出,這是因?yàn)?Go 客戶端庫(kù)默認(rèn)在我們暴露的全局默認(rèn)指標(biāo)注冊(cè)表中注冊(cè)了一些關(guān)于 promhttp 處理器和運(yùn)行時(shí)間相關(guān)的默認(rèn)指標(biāo),根據(jù)不同指標(biāo)名稱(chēng)的前綴可以看出:

        • go_*:以 go_ 為前綴的指標(biāo)是關(guān)于 Go 運(yùn)行時(shí)相關(guān)的指標(biāo),比如垃圾回收時(shí)間、goroutine 數(shù)量等,這些都是 Go 客戶端庫(kù)特有的,其他語(yǔ)言的客戶端庫(kù)可能會(huì)暴露各自語(yǔ)言的其他運(yùn)行時(shí)指標(biāo)。
        • promhttp_*:來(lái)自 promhttp 工具包的相關(guān)指標(biāo),用于跟蹤對(duì)指標(biāo)請(qǐng)求的處理。

        這些默認(rèn)的指標(biāo)是非常有用,但是更多的時(shí)候我們需要自己控制,來(lái)暴露一些自定義指標(biāo)。這就需要我們?nèi)?shí)現(xiàn)自定義的指標(biāo)了。

        添加自定義指標(biāo)

        接下來(lái)我們來(lái)自定義一個(gè)的 gauge 指標(biāo)來(lái)暴露當(dāng)前的溫度。創(chuàng)建一個(gè)新的文件 custom-metric/main.go,內(nèi)容如下所示:

        package?main

        import?(
        ?"net/http"

        ?"github.com/prometheus/client_golang/prometheus"
        ?"github.com/prometheus/client_golang/prometheus/promhttp"
        )

        func?main()?{
        ????//?創(chuàng)建一個(gè)沒(méi)有任何?label?標(biāo)簽的?gauge?指標(biāo)
        ?temp?:=?prometheus.NewGauge(prometheus.GaugeOpts{
        ??Name:?"home_temperature_celsius",
        ??Help:?"The?current?temperature?in?degrees?Celsius.",
        ?})

        ?//?在默認(rèn)的注冊(cè)表中注冊(cè)該指標(biāo)
        ?prometheus.MustRegister(temp)

        ?//?設(shè)置?gauge?的值為?39
        ?temp.Set(39)

        ?//?暴露指標(biāo)
        ?http.Handle("/metrics",?promhttp.Handler())
        ?http.ListenAndServe(":8080",?nil)
        }

        上面文件中和最初的文件就有一些變化了:

        • 我們使用 prometheus.NewGauge() 函數(shù)創(chuàng)建了一個(gè)自定義的 gauge 指標(biāo)對(duì)象,指標(biāo)名稱(chēng)為 home_temperature_celsius,并添加了一個(gè)注釋信息。
        • 然后使用 prometheus.MustRegister() 函數(shù)在默認(rèn)的注冊(cè)表中注冊(cè)了這個(gè) gauge 指標(biāo)對(duì)象。
        • 通過(guò)調(diào)用 Set() 方法將 gauge 指標(biāo)的值設(shè)置為 39。
        • 然后像之前一樣通過(guò) HTTP 暴露默認(rèn)的注冊(cè)表。

        需要注意的是除了 prometheus.MustRegister() 函數(shù)之外還有一個(gè) prometheus.Register() 函數(shù),一般在 golang 中我們會(huì)將 Mustxxx 開(kāi)頭的函數(shù)定義為必須滿足條件的函數(shù),如果不滿足會(huì)返回一個(gè) panic 而不是一個(gè) error 操作,所以如果這里不能正常注冊(cè)的話會(huì)拋出一個(gè) panic。

        現(xiàn)在我們來(lái)運(yùn)行這個(gè)程序:

        ????go?run?./custom-metric

        啟動(dòng)后重新訪問(wèn)指標(biāo)接口 http://localhost:8080/metrics,仔細(xì)對(duì)比我們會(huì)發(fā)現(xiàn)多了一個(gè)名為 home_temperature_celsius 的指標(biāo):

        ...
        #?HELP?home_temperature_celsius?The?current?temperature?in?degrees?Celsius.
        #?TYPE?home_temperature_celsius?gauge
        home_temperature_celsius?42
        ...

        這樣我們就實(shí)現(xiàn)了添加一個(gè)自定義的指標(biāo)的操作,整體比較簡(jiǎn)單,當(dāng)然在實(shí)際的項(xiàng)目中需要結(jié)合業(yè)務(wù)來(lái)確定添加哪些自定義指標(biāo)。

        自定義注冊(cè)表

        前面我們是使用 prometheus.MustRegister() 函數(shù)來(lái)將指標(biāo)注冊(cè)到全局默認(rèn)注冊(cè)中,此外我們還可以使用 prometheus.NewRegistry() 函數(shù)來(lái)創(chuàng)建和使用自己的非全局的注冊(cè)表。

        既然有全局的默認(rèn)注冊(cè)表,為什么我們還需要自定義注冊(cè)表呢?這主要是因?yàn)椋?/p>

        • 全局變量通常不利于維護(hù)和測(cè)試,創(chuàng)建一個(gè)非全局的注冊(cè)表,并明確地將其傳遞給程序中需要注冊(cè)指標(biāo)的地方,這也一種更加推薦的做法。
        • 全局默認(rèn)注冊(cè)表包括一組默認(rèn)的指標(biāo),我們有時(shí)候可能希望除了自定義的指標(biāo)之外,不希望暴露其他的指標(biāo)。

        下面的示例程序演示了如何創(chuàng)建、使用和暴露一個(gè)非全局注冊(cè)表對(duì)象,創(chuàng)建一個(gè)文件 custom-registry/main.go,內(nèi)容如下所示:

        package?main

        import?(
        ?"net/http"

        ?"github.com/prometheus/client_golang/prometheus"
        ?"github.com/prometheus/client_golang/prometheus/promhttp"
        )

        func?main()?{
        ?//?創(chuàng)建一個(gè)自定義的注冊(cè)表
        ?registry?:=?prometheus.NewRegistry()
        ?//?可選:?添加?process?和?Go?運(yùn)行時(shí)指標(biāo)到我們自定義的注冊(cè)表中
        ?registry.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
        ?registry.MustRegister(prometheus.NewGoCollector())

        ?//?創(chuàng)建一個(gè)簡(jiǎn)單呃 gauge 指標(biāo)。
        ?temp?:=?prometheus.NewGauge(prometheus.GaugeOpts{
        ??Name:?"home_temperature_celsius",
        ??Help:?"The?current?temperature?in?degrees?Celsius.",
        ?})

        ?//?使用我們自定義的注冊(cè)表注冊(cè)?gauge
        ?registry.MustRegister(temp)

        ?//?設(shè)置?gague?的值為?39
        ?temp.Set(39)

        ?//?暴露自定義指標(biāo)
        ?http.Handle("/metrics",?promhttp.HandlerFor(registry,?promhttp.HandlerOpts{Registry:?registry}))
        ?http.ListenAndServe(":8080",?nil)
        }

        上面我們沒(méi)有使用全局默認(rèn)的注冊(cè)表了,而是創(chuàng)建的一個(gè)自定義的注冊(cè)表:

        • 首先使用 prometheus.NewRegistry() 函數(shù)創(chuàng)建我們自己的注冊(cè)表對(duì)象。
        • 然后使用自定義注冊(cè)表對(duì)象上面的 MustRegister() 哈是來(lái)注冊(cè) guage 指標(biāo),而不是調(diào)用 prometheus.MustRegister() 函數(shù)(這會(huì)使用全局默認(rèn)的注冊(cè)表)。
        • 如果我們希望在自定義注冊(cè)表中也有進(jìn)程和 Go 運(yùn)行時(shí)相關(guān)的指標(biāo),我們可以通過(guò)實(shí)例化 Collector 收集器來(lái)添加他們。
        • 最后在暴露指標(biāo)的時(shí)候必須通過(guò)調(diào)用 promhttp.HandleFor() 函數(shù)來(lái)創(chuàng)建一個(gè)專(zhuān)門(mén)針對(duì)我們自定義注冊(cè)表的 HTTP 處理器,為了同時(shí)暴露前面示例中的 promhttp_* 相關(guān)的指標(biāo),我們還需要在 promhttp.HandlerOpts 配置對(duì)象的 Registry 字段中傳遞我們的注冊(cè)表對(duì)象。

        同樣我們重新運(yùn)行上面的自定義注冊(cè)表程序:

        ????go?run?./custom-metric

        啟動(dòng)后再次訪問(wèn)指標(biāo)接口 http://localhost:8080/metrics,可以發(fā)現(xiàn)和上面示例中的指標(biāo)數(shù)據(jù)是相同的。

        指標(biāo)定制

        Gauges

        前面的示例我們已經(jīng)了解了如何添加 gauge 類(lèi)型的指標(biāo),創(chuàng)建了一個(gè)沒(méi)有任何標(biāo)簽的指標(biāo),直接使用 prometheus.NewGauge() 函數(shù)即可實(shí)例化一個(gè) gauge 類(lèi)型的指標(biāo)對(duì)象,通過(guò) prometheus.GaugeOpts 對(duì)象可以指定指標(biāo)的名稱(chēng)和注釋信息:

        queueLength?:=?prometheus.NewGauge(prometheus.GaugeOpts{
        ?Name:?"queue_length",
        ?Help:?"The?number?of?items?in?the?queue.",
        })

        我們知道 gauge 類(lèi)型的指標(biāo)值是可以上升或下降的,所以我們可以為 gauge 指標(biāo)設(shè)置一個(gè)指定的值,所以 gauge 指標(biāo)對(duì)象暴露了 Set()Inc()、Dec()、Add()Sub() 這些函數(shù)來(lái)更改指標(biāo)值:

        //?使用?Set()?設(shè)置指定的值
        queueLength.Set(0)

        //?增加或減少
        queueLength.Inc()???//?+1:Increment the gauge by 1.
        queueLength.Dec()???//?-1:Decrement the gauge by 1.
        queueLength.Add(23)?//?Increment?by?23.
        queueLength.Sub(42)?//?Decrement?by?42.

        另外 gauge 儀表盤(pán)經(jīng)常被用來(lái)暴露 Unix 的時(shí)間戳樣本值,所以也有一個(gè)方便的方法來(lái)將 gauge 設(shè)置為當(dāng)前的時(shí)間戳:

        demoTimestamp.SetToCurrentTime()

        最終 gauge 指標(biāo)會(huì)被渲染成如下所示的數(shù)據(jù):

        #?HELP?queue_length?The?number?of?items?in?the?queue.
        #?TYPE?queue_length?gauge
        queue_length?42

        Counters

        要?jiǎng)?chuàng)建一個(gè) counter 類(lèi)型的指標(biāo)和 gauge 比較類(lèi)似,只是用 prometheus.NewCounter() 函數(shù)來(lái)初始化指標(biāo)對(duì)象:

        totalRequests?:=?prometheus.NewCounter(prometheus.CounterOpts{
        ?Name:?"http_requests_total",
        ?Help:?"The?total?number?of?handled?HTTP?requests.",
        })

        我們知道 counter 指標(biāo)只能隨著時(shí)間的推移而不斷增加,所以我們不能為其設(shè)置一個(gè)指定的值或者減少指標(biāo)值,所以該對(duì)象下面只有 Inc()Add() 兩個(gè)函數(shù):

        totalRequests.Inc()???//?+1:Increment the counter by 1.
        totalRequests.Add(23)?//?+n:Increment the counter by 23.

        當(dāng)服務(wù)進(jìn)程重新啟動(dòng)的時(shí)候,counter 指標(biāo)值會(huì)被重置為 0,不過(guò)不用擔(dān)心數(shù)據(jù)錯(cuò)亂,我們一般會(huì)使用的 rate() 函數(shù)會(huì)自動(dòng)處理。

        最終 counter 指標(biāo)會(huì)被渲染成如下所示的數(shù)據(jù):

        #?HELP?http_requests_total?The?total?number?of?handled?HTTP?requests.
        #?TYPE?http_requests_total?counter
        http_requests_total?7734

        Histograms

        創(chuàng)建直方圖指標(biāo)比 counter 和 gauge 都要復(fù)雜,因?yàn)樾枰渲冒延^測(cè)值歸入的 bucket 的數(shù)量,以及每個(gè) bucket 的上邊界。Prometheus 中的直方圖是累積的,所以每一個(gè)后續(xù)的 bucket 都包含前一個(gè) bucket 的觀察計(jì)數(shù),所有 bucket 的下限都從 0 開(kāi)始的,所以我們不需要明確配置每個(gè) bucket 的下限,只需要配置上限即可。

        同樣要?jiǎng)?chuàng)建直方圖指標(biāo)對(duì)象,我們使用 prometheus.NewHistogram() 函數(shù)來(lái)進(jìn)行初始化:

        requestDurations?:=?prometheus.NewHistogram(prometheus.HistogramOpts{
        ??Name:????"http_request_duration_seconds",
        ??Help:????"A?histogram?of?the?HTTP?request?durations?in?seconds.",
        ??// Bucket 配置:第一個(gè) bucket 包括所有在?0.05s 內(nèi)完成的請(qǐng)求,最后一個(gè)包括所有在10s內(nèi)完成的請(qǐng)求。
        ??Buckets:?[]float64{0.05,?0.1,?0.25,?0.5,?1,?2.5,?5,?10},
        })

        這里和前面不一樣的地方在于除了指定指標(biāo)名稱(chēng)和幫助信息之外,還需要配置 Buckets。如果我們手動(dòng)去枚舉所有的 bucket 可能很繁瑣,所以 Go 客戶端庫(kù)為為我們提供了一些輔助函數(shù)可以幫助我們生成線性或者指數(shù)增長(zhǎng)的 bucket,比如 prometheus.LinearBuckets()prometheus.ExponentialBuckets() 函數(shù)。

        直方圖會(huì)自動(dòng)對(duì)數(shù)值的分布進(jìn)行分類(lèi)和計(jì)數(shù),所以它只有一個(gè) Observe() 方法,每當(dāng)你在代碼中處理要跟蹤的數(shù)據(jù)時(shí),就會(huì)調(diào)用這個(gè)方法。例如,如果你剛剛處理了一個(gè) HTTP 請(qǐng)求,花了 0.42 秒,則可以使用下面的代碼來(lái)跟蹤。

        requestDurations.Observe(0.42)

        由于跟蹤持續(xù)時(shí)間是直方圖的一個(gè)常見(jiàn)用例,Go 客戶端庫(kù)就提供了輔助函數(shù),用于對(duì)代碼的某些部分進(jìn)行計(jì)時(shí),然后自動(dòng)觀察所產(chǎn)生的持續(xù)時(shí)間,將其轉(zhuǎn)化為直方圖,如下代碼所示:

        //?啟動(dòng)一個(gè)計(jì)時(shí)器
        timer?:=?prometheus.NewTimer(requestDurations)

        //?[...在應(yīng)用中處理請(qǐng)求...]

        //?停止計(jì)時(shí)器并觀察其持續(xù)時(shí)間,將其放進(jìn)?requestDurations?的直方圖指標(biāo)中去
        timer.ObserveDuration()

        直方圖指標(biāo)最終會(huì)生成如下所示的數(shù)據(jù):

        #?HELP?http_request_duration_seconds?A?histogram?of?the?HTTP?request?durations?in?seconds.
        #?TYPE?http_request_duration_seconds?histogram
        http_request_duration_seconds_bucket{le="0.05"}?4599
        http_request_duration_seconds_bucket{le="0.1"}?24128
        http_request_duration_seconds_bucket{le="0.25"}?45311
        http_request_duration_seconds_bucket{le="0.5"}?59983
        http_request_duration_seconds_bucket{le="1"}?60345
        http_request_duration_seconds_bucket{le="2.5"}?114003
        http_request_duration_seconds_bucket{le="5"}?201325
        http_request_duration_seconds_bucket{le="+Inf"}?227420
        http_request_duration_seconds_sum?88364.234
        http_request_duration_seconds_count?227420

        每個(gè)配置的存儲(chǔ)桶最終作為一個(gè)帶有 _bucket 后綴的計(jì)數(shù)器時(shí)間序列,使用 le(小于或等于) 標(biāo)簽指示該存儲(chǔ)桶的上限,具有上限的隱式存儲(chǔ)桶 +Inf 也暴露于比最大配置的存儲(chǔ)桶邊界花費(fèi)更長(zhǎng)的時(shí)間的請(qǐng)求,還包括使用后綴 _sum 累積總和和計(jì)數(shù) _count 的指標(biāo),這些時(shí)間序列中的每一個(gè)在概念上都是一個(gè) counter 計(jì)數(shù)器(只能上升的單個(gè)值),只是它們是作為直方圖的一部分創(chuàng)建的。

        Summaries

        創(chuàng)建和使用摘要與直方圖非常類(lèi)似,只是我們需要指定要跟蹤的 quantiles 分位數(shù)值,而不需要處理 bucket 桶,比如我們想要跟蹤 HTTP 請(qǐng)求延遲的第 50、90 和 99 個(gè)百分位數(shù),那么我們可以創(chuàng)建這樣的一個(gè)摘要對(duì)象:

        requestDurations?:=?prometheus.NewSummary(prometheus.SummaryOpts{
        ????Name:???????"http_request_duration_seconds",
        ????Help:???????"A?summary?of?the?HTTP?request?durations?in?seconds.",
        ????Objectives:?map[float64]float64{
        ??????0.5:?0.05,???//?第50個(gè)百分位數(shù),最大絕對(duì)誤差為0.05。
        ??????0.9:?0.01,???//?第90個(gè)百分位數(shù),最大絕對(duì)誤差為0.01。
        ??????0.99:?0.001,?//?第90個(gè)百分位數(shù),最大絕對(duì)誤差為0.001。
        ????},
        ??},
        )

        這里和前面不一樣的地方在于使用 prometheus.NewSummary() 函數(shù)初始化摘要指標(biāo)對(duì)象的時(shí)候,需要通過(guò) prometheus.SummaryOpts{} 對(duì)象的 Objectives 屬性指定想要跟蹤的分位數(shù)值。

        同樣摘要指標(biāo)對(duì)象創(chuàng)建后,跟蹤持續(xù)時(shí)間的方式和直方圖是完全一樣的,使用一個(gè) Observe() 函數(shù)即可:

        requestDurations.Observe(0.42)

        雖然直方圖桶可以跨維度匯總(如端點(diǎn)、HTTP 方法等),但這對(duì)于匯總 quantiles 分位數(shù)值來(lái)說(shuō)在統(tǒng)計(jì)學(xué)上是無(wú)效的。例如,你不能對(duì)兩個(gè)單獨(dú)的服務(wù)實(shí)例的第 90 百分位延遲進(jìn)行平均,并期望得到一個(gè)有效的整體第 90 百分位延遲。如果需要按維度進(jìn)行匯總,那么我們需要使用直方圖而不是摘要指標(biāo)。

        摘要指標(biāo)最終生成的指標(biāo)數(shù)據(jù)與直方圖非常類(lèi)似,不同之處在于使用 quantile 標(biāo)簽來(lái)表示分位數(shù)序列,并且這些序列沒(méi)有擴(kuò)展指標(biāo)名稱(chēng)的后綴:

        #?HELP?http_request_duration_seconds?A?summary?of?the?HTTP?request?durations?in?seconds.
        #?TYPE?http_request_duration_seconds?summary
        http_request_duration_seconds{quantile="0.5"}?0.052
        http_request_duration_seconds{quantile="0.90"}?0.564
        http_request_duration_seconds{quantile="0.99"}?2.372
        http_request_duration_seconds_sum?88364.234
        http_request_duration_seconds_count?227420

        標(biāo)簽

        到目前為止,我們還沒(méi)有為指標(biāo)對(duì)象添加任何的標(biāo)簽,要?jiǎng)?chuàng)建具有標(biāo)簽維度的指標(biāo),我們可以調(diào)用類(lèi)似于 NewXXXVec() 的構(gòu)造函數(shù)來(lái)初始化指標(biāo)對(duì)象:

        • NewGauge() 變成 NewGaugeVec()
        • NewCounter() 變成 NewCounterVec()
        • NewSummary() 變成 NewSummaryVec()
        • NewHistogram() 變成 NewHistogramVec()

        這些函數(shù)允許我們指定一個(gè)額外的字符串切片參數(shù),提供標(biāo)簽名稱(chēng)的列表,通過(guò)它來(lái)拆分指標(biāo)。

        例如,為了按照房子以及測(cè)量溫度的房間來(lái)劃分我們?cè)缙诘臏囟缺碇笜?biāo),可以這樣創(chuàng)建指標(biāo)。

        temp?:=?prometheus.NewGaugeVec(
        ??prometheus.GaugeOpts{
        ????Name:?"home_temperature_celsius",
        ????Help:?"The?current?temperature?in?degrees?Celsius.",
        ??},
        ??//?兩個(gè)標(biāo)簽名稱(chēng),通過(guò)它們來(lái)分割指標(biāo)。
        ??[]string{"house",?"room"},
        )

        然后要訪問(wèn)一個(gè)特有標(biāo)簽的子指標(biāo),需要在設(shè)置其值之前,用 houseroom 標(biāo)簽的各自數(shù)值,對(duì)產(chǎn)生的 gauge 向量調(diào)用 WithLabelValues() 方法來(lái)處理下:

        //?為?home=ydzs?和?room=living-room?設(shè)置指標(biāo)值
        temp.WithLabelValues("ydzs",?"living-room").Set(27)

        如果你喜歡在選擇的子指標(biāo)中明確提供標(biāo)簽名稱(chēng),可以使用效率稍低的 With() 方法來(lái)代替:

        temp.With(prometheus.Labels{"house":?"ydzs",?"room":?"living-room"}).Set(66)

        不過(guò)需要注意如果向這兩個(gè)方法傳遞不正確的標(biāo)簽數(shù)量或不正確的標(biāo)簽名稱(chēng),這兩個(gè)方法都會(huì)觸發(fā) panic。

        下面是我們按照 houseroom 標(biāo)簽維度區(qū)分指標(biāo)的完整示例,創(chuàng)建一個(gè)名為 label-metric/main.go 的新文件,內(nèi)容如下所示:

        package?main

        import?(
        ?"net/http"

        ?"github.com/prometheus/client_golang/prometheus"
        ?"github.com/prometheus/client_golang/prometheus/promhttp"
        )

        func?main()?{
        ????//?創(chuàng)建帶?house?和?room?標(biāo)簽的?gauge?指標(biāo)對(duì)象
        ?temp?:=?prometheus.NewGaugeVec(
        ??prometheus.GaugeOpts{
        ???Name:?"home_temperature_celsius",
        ???Help:?"The?current?temperature?in?degrees?Celsius.",
        ??},
        ??//?指定標(biāo)簽名稱(chēng)
        ??[]string{"house",?"room"},
        ?)

        ?//?注冊(cè)到全局默認(rèn)注冊(cè)表中
        ?prometheus.MustRegister(temp)

        ?//?針對(duì)不同標(biāo)簽值設(shè)置不同的指標(biāo)值
        ?temp.WithLabelValues("cnych",?"living-room").Set(27)
        ?temp.WithLabelValues("cnych",?"bedroom").Set(25.3)
        ?temp.WithLabelValues("ydzs",?"living-room").Set(24.5)
        ?temp.WithLabelValues("ydzs",?"bedroom").Set(27.7)

        ?//?暴露自定義的指標(biāo)
        ?http.Handle("/metrics",?promhttp.Handler())
        ?http.ListenAndServe(":8080",?nil)
        }

        上面代碼非常清晰了,運(yùn)行下面的程序:

        ????go?run?./label-metric

        啟動(dòng)完成后重新訪問(wèn)指標(biāo)端點(diǎn) http://localhost:8080/metrics,可以找到 home_temperature_celsius 指標(biāo)不同標(biāo)簽維度下面的指標(biāo)值:

        ...
        #?HELP?home_temperature_celsius?The?current?temperature?in?degrees?Celsius.
        #?TYPE?home_temperature_celsius?gauge
        home_temperature_celsius{house="cnych",room="bedroom"}?25.3
        home_temperature_celsius{house="cnych",room="living-room"}?27
        home_temperature_celsius{house="ydzs",room="bedroom"}?27.7
        home_temperature_celsius{house="ydzs",room="living-room"}?24.5
        ...

        注意:當(dāng)使用帶有標(biāo)簽維度的指標(biāo)時(shí),任何標(biāo)簽組合的時(shí)間序列只有在該標(biāo)簽組合被訪問(wèn)過(guò)至少一次后才會(huì)出現(xiàn)在 /metrics 輸出中,這對(duì)我們?cè)?PromQL 查詢的時(shí)候會(huì)產(chǎn)生一些問(wèn)題,因?yàn)樗M承r(shí)間序列一直存在,我們可以在程序第一次啟動(dòng)時(shí),將所有重要的標(biāo)簽組合預(yù)先初始化為默認(rèn)值。

        同樣的方式在其他幾個(gè)指標(biāo)類(lèi)型中使用標(biāo)簽的方法與上面的方式一致。

        瀏覽 106
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 欧美极品欧美精品欧美 | 人妻无码精品久久久久一区 | 日韩在线小视频 | 色秘 乱码一区二区三区唱戏 | 久久水蜜桃 |