Как переоценить promhttp.Handler на изменение базы данных? - PullRequest
1 голос
/ 02 июня 2019

Я, возможно, злоупотребляю promhttp.Handler(), чтобы реализовать сценарий использования для моего микросервиса, чтобы сообщить мне:

  • версия
  • , если он имеет подключение к базе данных

Если есть лучший способ мониторинга моих микросервисов, дайте мне знать!

Я не уверен, как структурировать дескриптор таким образом, чтобы при вызове / metrics вызывался db.Ping () переоценивается.

https://s.natalian.org/2019-06-02/msping.mp4

package main

import (
    "log"
    "net/http"
    "os"

    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "github.com/jmoiron/sqlx"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

const version = "0.0.1"

type App struct {
    Router *mux.Router
    DB     *sqlx.DB
}

func main() {
    a := App{}
    a.Initialize()

    log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), a.Router))
}

func (a *App) Initialize() {
    connectionString := "root:secret@tcp(localhost:3306)/rest_api_example?multiStatements=true&sql_mode=TRADITIONAL&timeout=5s"
    var err error
    a.DB, err = sqlx.Open("mysql", connectionString)
    if err != nil {
        log.Fatal(err)
    }

    microservicecheck := prometheus.NewGaugeVec(
        prometheus.GaugeOpts{
            Name: "mscheck",
            Help: "Version with DB ping check",
        },
        []string{
            "commit",
        },
    )

    if a.DB.Ping() == nil {
        microservicecheck.WithLabelValues(version).Set(1)
    } else {
        microservicecheck.WithLabelValues(version).Set(0)
    }

    prometheus.MustRegister(microservicecheck)

    a.Router = mux.NewRouter()
    a.initializeRoutes()
}

func (a *App) initializeRoutes() {
    a.Router.Handle("/metrics", promhttp.Handler()).Methods("GET")
}

https://play.golang.org/p/9DdXnz77S55

1 Ответ

1 голос
/ 20 июня 2019

Вы также можете добавить перехватчик промежуточного программного обеспечения, который выполняет подпрограмму перед полетом (т. Е. Ваш тест ping) перед вызовом promhttp.Handler(). Однако, во время сбора, я думаю, что метрики уже должны были быть подсчитаны; и не генерируется в момент сбора. Итак ...

Попробуйте отдельную подпрограмму, которая будет регулярно проверять состояние соединения с БД. Это позволяет избежать беспорядочных зацепок или пользовательских коллекторов:

var pingPollingFreq = 5 * time.Second // this should probably match the Prometheus scrape interval

func (a *App) Initialize() {       
    // ...

    prometheus.MustRegister(microservicecheck)

    go func() {
        for {
            if a.DB.Ping() == nil {
                microservicecheck.WithLabelValues(version).Set(1)
            } else {
                microservicecheck.WithLabelValues(version).Set(0)
            }
            time.Sleep(pingPollingFreq)
        }
    }()

    prometheus.MustRegister(microservicecheck)

    // ...
}
...