解析 Prometheus 数据
使用 HTTP GET 请求从 Prometheus 获取指标只是第一步。下一个挑战在于解析数据并提取其组成部分。本文探讨如何解析 Prometheus 数据,重点介绍 EBNF 包和替代解决方案。
使用 EBNF 解析
中的 EBNF(扩展巴科斯-诺尔范式)包Go 提供了一种定义和解析语法的方法。虽然它可以用来解析 Prometheus 数据,但它需要大量的努力和体力劳动。此方法的指数必须精心创建语法,预测所有可能的数据变化以确保准确解析。
利用 Prometheus 的 expfmt
您不必依赖复杂的语法定义,而是可以利用Prometheus作者自己开发的一个包——expfmt。该 Go 库专门用于编码和解码 Prometheus Exposition Format(基于 EBNF)。它的易用性和开箱即用的功能使其成为解析 Prometheus 数据的理想选择。
expfmt 的示例
考虑以下 Prometheus 示例data:
# 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
下面的 Go 代码演示了如何使用expfmt:
package main import ( "flag" "fmt" "log" "os" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" ) 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) } } 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 fatal(err error) { if err != nil { log.Fatalln(err) } }
运行此程序会产生以下输出:
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 >
排查格式问题
确保 Prometheus 数据遵循正确的格式要求。每行必须以换行符“n”结束。与此格式的偏差,包括“r”或“rn”,将触发协议错误。
以上是如何在Go中高效解析Prometheus数据?的详细内容。更多信息请关注PHP中文网其他相关文章!