从文件中解析普罗米修斯指标并更新计数器
Posted
技术标签:
【中文标题】从文件中解析普罗米修斯指标并更新计数器【英文标题】:Parsing prometheus metrics from file and updating counters 【发布时间】:2021-04-17 07:46:52 【问题描述】:我有一个按批次定期运行的 go 应用程序。每次运行时,它都应该从文件中读取一些 prometheus 指标,运行其逻辑,更新成功/失败计数器,并将指标写回文件。
通过查看How to parse Prometheus data 和godocs for prometheus,我能够读取文件,但我不知道如何使用expfmt.ExtractSamples()
返回的值更新app_processed_total
。
这是我到目前为止所做的。有人可以告诉我应该如何从这里开始吗?如何将我输入的 Vector 类型转换为 CounterVec
?
package main
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/common/model"
)
var (
fileOnDisk = prometheus.NewRegistry()
processedTotal = prometheus.NewCounterVec(prometheus.CounterOpts
Name: "app_processed_total",
Help: "Number of times ran",
, []string"status")
)
func doInit()
prometheus.MustRegister(processedTotal)
func recordMetrics()
go func()
for
processedTotal.With(prometheus.Labels"status": "ok").Inc()
time.Sleep(5 * time.Second)
()
func readExistingMetrics()
var parser expfmt.TextParser
text := `
# HELP app_processed_total Number of times ran
# TYPE app_processed_total counter
app_processed_totalstatus="ok" 300
`
parseText := func() ([]*dto.MetricFamily, error)
parsed, err := parser.TextToMetricFamilies(strings.NewReader(text))
if err != nil
return nil, err
var result []*dto.MetricFamily
for _, mf := range parsed
result = append(result, mf)
return result, nil
gatherers := prometheus.Gatherers
fileOnDisk,
prometheus.GathererFunc(parseText),
gathering, err := gatherers.Gather()
if err != nil
fmt.Println(err)
fmt.Println("gathering: ", gathering)
for _, g := range gathering
vector, err := expfmt.ExtractSamples(&expfmt.DecodeOptions
Timestamp: model.Now(),
, g)
fmt.Println("vector: ", vector)
if err != nil
fmt.Println(err)
// How can I update processedTotal with this new value?
func main()
doInit()
readExistingMetrics()
recordMetrics()
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe("localhost:2112", nil)
【问题讨论】:
【参考方案1】:我相信你需要使用processedTotal.WithLabelValues("ok").Inc()
或类似的东西。
更完整的例子在这里
func ExampleCounterVec()
httpReqs := prometheus.NewCounterVec(
prometheus.CounterOpts
Name: "http_requests_total",
Help: "How many HTTP requests processed, partitioned by status code and HTTP method.",
,
[]string"code", "method",
)
prometheus.MustRegister(httpReqs)
httpReqs.WithLabelValues("404", "POST").Add(42)
// If you have to access the same set of labels very frequently, it
// might be good to retrieve the metric only once and keep a handle to
// it. But beware of deletion of that metric, see below!
m := httpReqs.WithLabelValues("200", "GET")
for i := 0; i < 1000000; i++
m.Inc()
// Delete a metric from the vector. If you have previously kept a handle
// to that metric (as above), future updates via that handle will go
// unseen (even if you re-create a metric with the same label set
// later).
httpReqs.DeleteLabelValues("200", "GET")
// Same thing with the more verbose Labels syntax.
httpReqs.Delete(prometheus.Labels"method": "GET", "code": "200")
本文摘自 Github 上的Promethus examples
要使用向量的值,您可以执行以下操作:
vectorFloat, err := strconv.ParseFloat(vector[0].Value.String(), 64)
if err != nil
panic(err)
processedTotal.WithLabelValues("ok").Add(vectorFloat)
这是假设您在响应中只会得到一个向量值。向量的值存储为字符串,但您可以使用 strconv.ParseFloat
方法将其转换为浮点数。
【讨论】:
有没有办法让我获得的价值进入 CounterVec?我想一种想象的方式是,如果将 CounterVec 序列化到文件中,然后将其读回。 是的你可以使用.Add
方法如果你想指定一个数字来增加,存储在向量中的度量值存储为一个字符串,所以你需要做一些类型转换来得到它变成float64
接受的.Add
。更新了上面的例子。
谢谢。我想在app_processed_totalstatus="ok"
的情况下,我将不得不进行一些字符串操作来拆分并从vector[0].Metric.String() 中获取度量和标签。这比我想象的要复杂得多。以上是关于从文件中解析普罗米修斯指标并更新计数器的主要内容,如果未能解决你的问题,请参考以下文章