簡單使用
package main
import (
"context"
"github.com/prometheus/client_golang/api"
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
"github.com/prometheus/common/model"
log "github.com/sirupsen/logrus"
"time"
)
func main() {
// 創(chuàng)建一個 prom 客戶端
client,err := api.NewClient(api.Config{
Address: "http://localhost:9090",
})
if err != nil{
log.Fatalf("init client failed! %s", err)
}
// 創(chuàng)建一個 api v1客戶端
v1Api := v1.NewAPI(client)
query := `node_cpu_seconds_total`
result, warnings, err := v1Api.Query(context.Background(), query, time.Now())
if err != nil{
log.Fatalf("query failed, %s", err)
}
if len(warnings) > 0{
log.Info("Warning,",warnings)
}
log.Infof("ResultTypeis: %s", result.Type())
vector,ok := result.(model.Vector)
if !ok {
log.Info("result is not a vector")
return
}
// 遍歷結(jié)果向量中的每個樣本
for _, sample := range vector {
log.Infof("Metrics: %s, Value: %s\n", sample.String(), sample.Value)
}
}
日常使用總結(jié)
查詢方法
在 PromQL 中,主要有兩種類型的查詢方法:瞬時查詢(instant query)和區(qū)間查詢(range query)。他們的主要差異在于所需參數(shù)的不通侍咱,并且適用的場景也有所不同什湘。
- 瞬時查詢 (Instant Query)
瞬時查詢是最常見的一種查詢類型猫胁,其特點(diǎn)是在指定的時間點(diǎn)上取樣一次,這種查詢常用來查看當(dāng)前狀態(tài)下的指標(biāo)值剂买,例如查看當(dāng)前時刻的 cpu 負(fù)載,網(wǎng)絡(luò)流量等癌蓖。
//例如查詢當(dāng)前時間 cpu 的節(jié)點(diǎn)消耗的總 CPU 時間
query := `node_cpu_seconds_total`
result, warnings, err := v1Api.Query(context.Background(), query, time.Now())
- 區(qū)間查詢(Range Query)
區(qū)間查詢則允許用戶指定一個時間窗口瞬哼,并在該窗口的每一段時間點(diǎn)上采樣一次,這種查詢常用來觀察一段時期內(nèi)的指標(biāo)變化趨勢租副,例如查看最近 7 天的平均 cpu 負(fù)載坐慰,近一個月的網(wǎng)絡(luò)流量峰值等等
//查詢了過去 60 分鐘內(nèi)每 5 分鐘的節(jié)點(diǎn)空閑 CPU 時間的變化速率。
query := `rate(node_cpu_seconds_total{mode="idle"}[5m])`
stepDuration := 15 * time.Minute // Set your desired step duration here
endTime := time.Now()
startTime := endTime.Add(-60 * time.Minute)
rng := v1.Range{
Start: startTime,
End: endTime,
Step: stepDuration,
}
result, warnings, err := v1Api.QueryRange(context.Background(), query, rng)
查詢結(jié)果
- Scalar Result
Scalar結(jié)果通常用于只返回一個簡單數(shù)字的查詢用僧,例如計算某個特定的計數(shù)器的總和结胀,例如,查看k8s集群中有多少個 pod责循。我們可以把查詢語句寫成count(kube_pod_info)
// 構(gòu)建查詢表達(dá)式
query := `sum(node_memory_MemTotal_bytes) / 1024 / 1024`
// 執(zhí)行查詢
result, _, err := v1Api.Query(context.Background(), query, time.Now())
if err != nil {
log.Fatal(err)
}
// 將結(jié)果斷言為標(biāo)量類型
scalar, ok := result.(*model.Scalar)
if !ok {
log.Fatal("Unexpected query result type")
}
// 輸出標(biāo)量值
log.Infof("The result is %f\n", scalar.Value)
- Vector Result
Vector通常用于返回一組帶有標(biāo)簽的指標(biāo)糟港,例如正在運(yùn)行的所有 pod 的數(shù)量
query := `kube_pod_info{namespace='prometheus'}`
result, _, err := v1Api.Query(context.Background(), query, time.Now())
vector, ok := result.(model.Vector)
if !ok {
log.Error("Unexpected query result type")
return
}
for _, sample := range vector {
// 獲取標(biāo)簽的值
namespace := sample.Metric["namespace"]
podName := sample.Metric["pod"]
log.Infof("Metrics: namespace=%s, pod=%s, Value: %s\n", namespace, podName, sample.Value)
}
- Matrix Result
Matrix 結(jié)果通常用于返回一段時間范圍內(nèi)的歷史數(shù)據(jù),例如過去一天 cpu 利用率的變化趨勢院仿,例如秸抚,我們可以寫這樣一個表達(dá)式:
rate(node_cpu_seconds_total{mode="idle"}[5m])
速和,它的結(jié)果就是一個矩陣。
特別的剥汤,對于包含聚合函數(shù)的查詢颠放,如sum()、avg()等吭敢,Prometheus也會返回一個樣本流碰凶,但其中只有一條記錄,即聚合后的結(jié)果省有。這種情況下痒留,你也無法將其轉(zhuǎn)換為model.Vector類型,因為它不是一個向量蠢沿,而是一個樣本流伸头。
query := `rate(node_cpu_seconds_total{mode="idle"}[5m])`
stepDuration := 15 * time.Minute // 設(shè)置您所需的步長(時間間隔)在這里
endTime := time.Now()
startTime := endTime.Add(-60 * time.Minute)
rng := v1.Range{
Start: startTime,
End: endTime,
Step: stepDuration,
}
result, _, err := v1Api.QueryRange(context.Background(), query, rng)
if err != nil {
log.Fatal(err)
}
matrix, ok := result.(model.Matrix)
if !ok {
log.Fatalf("unexpected result type: %T", result)
}
for _, stream := range matrix {
fmt.Println("Metric:", stream.Metric)
for _, sample := range stream.Values {
fmt.Printf("Time: %s, Value: %s\n", sample.Timestamp, sample.Value)
}
}
總結(jié)
本文針對 prometheus golang 客戶端進(jìn)行了簡單的使用介紹,當(dāng)查詢設(shè)計多維度時舷蟀,Pronetheus 會返回一個樣本流而不是單個樣本恤磷,以下是一個處理多種情況的示例,僅供參考
switch result.Type() {
case model.ValScalar:
scalar := result.(*model.Scalar)
fmt.Println("Scalar value:", scalar.Value)
case model.ValVector:
vector := result.(model.Vector)
for _, sample := range vector {
fmt.Println("Sample metric:", sample.Metric, " Sample value:", sample.Value)
}
case model.ValMatrix:
matrix := result.(model.Matrix)
for _, stream := range matrix {
fmt.Println("Stream values:")
for _, point := range stream.Values {
fmt.Println("\tPoint timestamp:", point.Timestamp, " Point value:", point.Value)
}
}
default:
fmt.Println("Unknown type of result")
}