Как обновить значения метрик в экспортере прометея (Голанг)
Я начинаю писать собственный экспортер прометея, используя Голанг. Я думаю, что я получил основы, но я не знаю, что именно делать, чтобы получить актуальную стоимость метрики. Использование Set делает это только один раз. Это не меняется во время выполнения.
Что у меня так далеко:
package main
import (
"log"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"time"
"io/ioutil"
"github.com/tidwall/gjson"
"strconv"
)
var (
sidekiqProcessed = setGaugeMetric("sidekiq_processed", "Sidekiq Processed", "lable", "lablevalue")
)
func setGaugeMetric(name string, help string, label string, labelvalue string) (prometheusGauge prometheus.Gauge) {
var (
gaugeMetric = prometheus.NewGauge(prometheus.GaugeOpts{
Name: name,
Help: help,
ConstLabels: prometheus.Labels{label: labelvalue},
})
)
return gaugeMetric
}
func getSidekiqProcessed() (sidekiq float64) {
body := getContent("http://example.com/sidekiq/stats")
processed := gjson.Get(body, "sidekiq.processed")
conv, err := strconv.ParseFloat(processed.String(), 64)
if err != nil {
log.Fatal(err)
}
return conv
}
func getContent(url string) (body string) {
httpClient := &http.Client{Timeout: 10 * time.Second}
res, err := httpClient.Get(url)
if err != nil {
log.Fatal(err)
}
content, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
return string(content)
}
func init() {
prometheus.MustRegister(sidekiqProcessed)
}
func main() {
sidekiqProcessed.Set(getSidekiqProcessed())
// The Handler function provides a default handler to expose metrics
// via an HTTP server. "/metrics" is the usual endpoint for that.
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))
}
Прочитайте что-нибудь о Collector, но не знаете, как это реализовать. Может ли кто-нибудь помочь мне завершить / исправить мой код, чтобы значение метрики также обновлялось во время выполнения?
3 ответа
Вот пример пользовательского сборщика (из https://www.robustperception.io/setting-a-prometheus-counter):
package main
import "github.com/prometheus/client_golang/prometheus"
type MyCollector struct {
counterDesc *prometheus.Desc
}
func (c *MyCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.counterDesc
}
func (c *MyCollector) Collect(ch chan<- prometheus.Metric) {
value := 1.0 // Your code to fetch the counter value goes here.
ch <- prometheus.MustNewConstMetric(
c.counterDesc,
prometheus.CounterValue,
value,
)
}
func NewMyCollector() *MyCollector {
return &MyCollector{
counterDesc: prometheus.NewDesc("my_counter_total", "Help string", nil, nil),
}
}
// To hook in the collector: prometheus.MustRegister(NewMyCollector())
Возможно, вы захотите вместо этого реализовать сборщик и выполнить запрос http, когда сервер Prometheus очищается. Смотрите лучшие практики.
При реализации коллектора для вашего экспортера вы никогда не должны использовать обычный метод прямого инструментирования, а затем обновлять метрики для каждой очистки.
Скорее создавайте новые метрики каждый раз. В Go это делается с помощью MustNewConstMetric в вашем методе Update(). Для Python см. https://github.com/prometheus/client_python, а для Java создайте список в вашем методе сбора, см. Пример в StandardExports.java.
Библиотека github.com/prometheus/client_golang может оказаться нетривиальной при написании экспортеров Prometheus на Go. Вместо этого попробуйте библиотеку https://pkg.go.dev/github.com/VictoriaMetrics/metrics .В целом намного проще в использовании. См. следующий код в качестве примера, который позволяет динамически обновлять
sidekiq_processed
метрика с заданной меткой:
import (
"fmt"
"github.com/VictoriaMetrics/metrics"
)
// UpdateSidekiqProcessed updates `sidekiq_processed{label="<labelValue>"}` metric to the given value
func UpdateSidekiqProcessed(labelValue string, value float64) {
metricName := fmt.Sprintf("sidekiq_processed{label=%q}", labelValue)
metrics.GetOrCreateFloatCounter(metricName).Set(value)
}