将 Prometheus 抓取的数据转换为数组

Convert Prometheus scraped data into an array

我从 Prometheus 抓取了数据,响应如下。我想使用 Go 将维度数据放入数组(用于操作)。谁能帮帮我。谢谢 :)

func main() {
    resp, err := http.Get("http://desktop-o1hkgm7:9090/federate?match%5B%5D=%7Bdialer_name%3D%22alertmanager%22%7D")
    if err != nil {
        log.Fatalln(err)
    }
    //We Read the response body on the line below.
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    //Convert the body to type string
    sb := string(body)
    log.Printf(sb)
}

回复如下:

# TYPE net_conntrack_dialer_conn_attempted_total untyped
net_conntrack_dialer_conn_attempted_total{dialer_name="alertmanager",instance="localhost:9090",job="prometheus"} 0 1609568651186
# TYPE net_conntrack_dialer_conn_closed_total untyped
net_conntrack_dialer_conn_closed_total{dialer_name="alertmanager",instance="localhost:9090",job="prometheus"} 0 1609568651186
# TYPE net_conntrack_dialer_conn_established_total untyped
net_conntrack_dialer_conn_established_total{dialer_name="alertmanager",instance="localhost:9090",job="prometheus"} 0 1609568651186
# TYPE net_conntrack_dialer_conn_failed_total untyped
net_conntrack_dialer_conn_failed_total{dialer_name="alertmanager",instance="localhost:9090",job="prometheus",reason="refused"} 0 1609568651186
"prometheus",reason="timeout"} 0 1609568651186
net_conntrack_dialer_conn_failed_total{dialer_name="alertmanager",instance="localhost:9090",job="prometheus",reason="unknown"} 0 1609568651186

我在获取键和值后得到了这个值。我可以遍历 'name' 和 'value' 内部指标吗?如果可能,我该怎么做?我试过了,但显示无法通过 MetricFamily 循环显示。

Image

OP 在解释 he/she 实际想要什么时不是很清楚。 OP 所指的输出是“Prometheus Exposition Format”。这是 EBNF 语法,最好用 metric_namelabel_namelabel_value 等来代替 get the dimension data into an array (for manipulation).

阐述格式:

metric_name [
  "{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]

我假设的是,对于每个 metric_name,OP 想要遍历 labels,即 label_namelabel_value.

我将其标记为重复,因为我之前回答过一个非常相似的问题并且要达到要求,只需要进行微小的更改。

在以下程序中,存在指标的源文件(以说明格式)存储在本地文件系统中。因此,一种更改它的方法是它通过 HTTP 获取指标,然后循环遍历每个 metric_name.

的标签
  • 示例输入:
# HELP net_conntrack_dialer_conn_attempted_total
# TYPE net_conntrack_dialer_conn_attempted_total untyped
net_conntrack_dialer_conn_attempted_total{dialer_name="federate",instance="localhost:9090",job="prometheus"} 1 1608520832877
  • 示例输出:
KEY: net_conntrack_dialer_conn_attempted_total
VAL: name:"dialer_name" value:"federate"
VAL: name:"instance" value:"localhost:9090"
VAL: name:"job" value:"prometheus"

代码:

package main

import (
    "flag"
    "fmt"
    "log"
    "os"

    dto "github.com/prometheus/client_model/go"
    "github.com/prometheus/common/expfmt"
)

func fatal(err error) {
    if err != nil {
        log.Fatalln(err)
    }
}

func parseMetricFamily(path string) (map[string]*dto.MetricFamily, error) {
    reader, err := os.Open(path)
    if err != nil {
        return nil, err
    }

    var parser expfmt.TextParser
    mf, err := parser.TextToMetricFamilies(reader)
    if err != nil {
        return nil, err
    }
    return mf, nil
}

func main() {
    f := flag.String("f", "", "set filepath")
    flag.Parse()

    mf, err := parseMetricFamily(*f)
    fatal(err)

    for k, v := range mf {
        fmt.Printf("KEY: %v\n", k)
        for _, m := range v.Metric {
            for _, l := range m.Label {
                fmt.Printf("VAL: %v\n", l)
            }
        }
    }
}