【问题标题】:Extract Prometheus Metrics in Go在 Go 中提取 Prometheus 指标
【发布时间】:2020-08-18 15:23:37
【问题描述】:

我是 Golang 的新手,我想做的是查询 Prometheus 并将查询结果保存在具有所有时间戳及其度量值的对象(例如地图)中。 我从这个示例代码开始,只做了一些更改 (https://github.com/prometheus/client_golang/blob/master/api/prometheus/v1/example_test.go)

func getFromPromRange(start time.Time, end time.Time, metric string) model.Value {
    client, err := api.NewClient(api.Config{
        Address: "http://localhost:9090",
    })
    if err != nil {
        fmt.Printf("Error creating client: %v\n", err)
        os.Exit(1)
    }
    v1api := v1.NewAPI(client)
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    r := v1.Range{
        Start: start,
        End:   end,
        Step:  time.Second,
    }
    result, warnings, err := v1api.QueryRange(ctx, metric, r) 
    if err != nil {
        fmt.Printf("Error querying Prometheus: %v\n", err)
        os.Exit(1)
    }
    if len(warnings) > 0 {
        fmt.Printf("Warnings: %v\n", warnings)
    }
    fmt.Printf("Result:\n%v\n", result)

    return result
}

打印的结果例如: "TEST{instance="localhost:4321", job="realtime"} =>\n21 @[1597758502.337]\n22 @[1597758503.337]...

这些实际上是 Prometheus 上的正确值和时间戳。如何将这些时间戳和值插入到地图对象(或我可以在代码中使用的其他类型的对象)中?

【问题讨论】:

  • 没有“地图对象”之类的东西,它只是一张地图,Tour of Go 中介绍了使用地图,我建议您完整阅读以熟悉基础知识语言。

标签: go prometheus


【解决方案1】:

来自QueryRange 的结果类型为model.Matrix

这将包含一个*SampleStream 类型的指针。由于您的示例仅包含一个 SampleStream,我们可以直接访问第一个。

SampleStream 然后具有 []SamplePair 类型的 MetricValues。您的目标是样本对的切片。在此之上,我们可以迭代并构建例如地图。

mapData := make(map[model.Time]model.SampleValue)

for _, val := range result.(model.Matrix)[0].Values {
    mapData[val.Timestamp] = val.Value
}

fmt.Println(mapData)

【讨论】:

  • 你能否解释一下这个操作result.(model.Matrix)[0]。据我了解,您将结果投射到model.Matrix 然后拿起第一个,对吗?
  • 正是@IanZhang。如果您有多个 SampleStream,则对它们进行迭代是有意义的。出于简单的原因和作者只有一个的事实,该示例直接访问第一个元素。
【解决方案2】:

您必须知道返回的结果类型。例如,model.Value 可以是 Scalar、Vector、Matrix 或 String 类型。这些类型中的每一种都有自己获取数据和时间戳的方式。例如,一个 Vector 有一个 Sample 类型的数组,其中包含您要查找的数据。如果您想深入了解,godocs 和 prom/go 客户端的 github 存储库有非常好的文档。

【讨论】:

    【解决方案3】:

    或许你可以在本期找到答案

    https://github.com/prometheus/client_golang/issues/194

    switch {
            case val.Type() == model.ValScalar:
                scalarVal := val.(*model.Scalar)
                // handle scalar stuff
            case val.Type() == model.ValVector:
                vectorVal := val.(model.Vector)
                for _, elem := range vectorVal {
                    // do something with each element in the vector
            // etc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多