Как заставить обновлять значение метрики exporter для prometheus на golang
почтенные граждане!
Судьба заставила меня заняться изготовлением собственного экспортера для "Prometheus" на golang. С тем и другим столкнулся впервые. Экспотер должен "по просьбе" "Prometheus"-а обращаться к таблице в базе данных postgresql, вычитывать из нее одну запись, и одно поле из записи возвращать "Prometheus"-у.
Гуглил, комбинировал, на текущий момент получил код, который приведен ниже. Проблема в том, что код в main() выполняется один раз при старте, успешно запускется http-сервер, и далее ничего не происходит. netstat-ом вижу, что сервер слушает порт, "Prometheus" считает, что экспотрер работает правильно, но при этом значение метрики в "Prometheus" остается то, которое было определено при старте скрипта, хотя, достоверно, в базу пишутся разные новые значения.
Аналогичный экспортер сделал на python-е, который мало-мало знаю - там работает нормально. Подскажите, как заставить сервер на golang-e, в ответ на запросы "Prometheus", возвращать актуальные значение метрики.
package main
import (
"database/sql"
"fmt"
"time"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
_ "github.com/lib/pq"
)
type mtr struct{
id int
moment time.Time
cpu_load float64
}
func main() {
metric := prometheus.NewGauge(prometheus.GaugeOpts{Name: "example_gauge", Help: "An example gauge metric",},)
prometheus.MustRegister(metric)
metric.Set(get_metrics())
http.Handle("/metrics", promhttp.Handler())
fmt.Println("Starting web server\n")
err := http.ListenAndServe(":9990", nil)
if err != nil {
fmt.Println("http.ListenAndServer: %v\n", err)
}
}
func get_metrics() float64 {
connStr := "host=192.168.208.101 port=5432 user=masterdb password=passwdb dbname=edudb sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
panic(err)
}
defer db.Close()
if db != nil {
fmt.Println("Is Connect to db")
}
row := db.QueryRow("SELECT id, curr_time, cpu_load FROM edutbl ORDER BY id DESC LIMIT 1;")
if err != nil {
panic(err)
}
fmt.Println("Is Row")
m := mtr{}
err = row.Scan(&m.cpu_load, &m.moment, &m.cpu_load)
if err != nil {
fmt.Println(err)
}
fmt.Println(m.cpu_load)
fmt.Println("Hendler")
fmt.Println("L-n-S")
return m.cpu_load
}
Ответы (1 шт):
Вам нужно реализовать свой собственный Collector
Метод Collector.Collect
вызывается в тот момент, когда прометей опрашивает процесс о новых значениях метрик. Посмотрите пример
В вашем коде вы устанавливаете метрику только один раз вызовом metric.Set(get_metrics())
. Неудивительно, что она не обновляется со временем.