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 格式。
有人可以指出我解析上述数据的正确方向吗?
已经有一个很好的软件包可以做到这一点,它是由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 发布的输入中的格式问题:
参考:
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
用于行尾。