如何解析 Prometheus 数据

Sij*_*rai 2 ebnf go amazon-cloudwatch prometheus

我已经能够通过发送 HTTP GET 来获取指标,如下所示:

# TYPE net_conntrack_dialer_conn_attempted_total untyped net_conntrack_dialer_conn_attempted_total{dialer_name="federate",instance="localhost:9090",job="prometheus"} 1 1608520832877
Run Code Online (Sandbox Code Playgroud)

现在我需要解析这些数据并获得对每条数据的控制,以便我可以像 json 一样转换 tand 格式。

我一直在研究 Go 中的ebnf 包ebnf 包

有人可以指出我解析上述数据的正确方向吗?

p9s*_*9sh 7

已经有一个很好的软件包可以做到这一点,它是由Prometheus 的作者自己提供的。

他们编写了一堆 Go 库,这些库在Prometheus组件和库之间共享。它们被认为是 Prometheus 内部的,但您可以使用它们。

参考:github.com/prometheus/common doc。有一个包expfmt可以解码和编码Prometheus 的 Exposition 格式( Link )。是的,它遵循EBNF语法,因此ebnf也可以使用包,但您是expfmt开箱即用的。

使用的包:expfmt

样本输入:

# 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
Run Code Online (Sandbox Code Playgroud)

示例程序:

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 parseMF(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 := parseMF(*f)
    fatal(err)

    for k, v := range mf {
        fmt.Println("KEY: ", k)
        fmt.Println("VAL: ", v)
    }
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

KEY:  net_conntrack_dialer_conn_attempted_total
VAL:  name:"net_conntrack_dialer_conn_attempted_total" type:UNTYPED metric:<label:<name:"dialer_name" value:"federate" > label:<name:"instance" value:"localhost:9090" > label:<name:"job" value:"prometheus" > untyped:<value:1 > timestamp_ms:1608520832877 >
Run Code Online (Sandbox Code Playgroud)

因此,expfmt对于您的用例来说,这是一个不错的选择。

更新:OP 发布的输入中的格式问题:

参考:

  1. https://github.com/prometheus/pushgateway/issues/147#issuecomment-368215305

  2. https://github.com/prometheus/pushgateway#command-line

Note that in the text protocol, each line has to end with a line-feed
character (aka 'LF' or '\n'). Ending a line in other ways, e.g. with 
'CR' aka '\r', 'CRLF' aka '\r\n', or just the end of the packet, will
result in a protocol error.
Run Code Online (Sandbox Code Playgroud)

但是从错误消息中,我可以看到\r放置中存在字符,这是设计不可接受的。所以\n用于行尾。