forked from TrueCloudLab/frostfs-s3-gw
[#600] Add health metric
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
757600608c
commit
89d240d831
2 changed files with 55 additions and 38 deletions
|
@ -35,6 +35,8 @@ type (
|
|||
obj layer.Client
|
||||
api api.Handler
|
||||
|
||||
metrics GateMetricsCollector
|
||||
|
||||
maxClients api.MaxClients
|
||||
|
||||
webDone chan struct{}
|
||||
|
@ -45,6 +47,10 @@ type (
|
|||
KeyFile string
|
||||
CertFile string
|
||||
}
|
||||
|
||||
GateMetricsCollector interface {
|
||||
SetHealth(int32)
|
||||
}
|
||||
)
|
||||
|
||||
func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
||||
|
@ -57,6 +63,8 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
|||
obj layer.Client
|
||||
nc *notifications.Controller
|
||||
|
||||
gateMetrics GateMetricsCollector
|
||||
|
||||
prmPool pool.InitParameters
|
||||
|
||||
reBalance = defaultRebalanceInterval
|
||||
|
@ -180,6 +188,10 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
|||
l.Fatal("could not initialize API handler", zap.Error(err))
|
||||
}
|
||||
|
||||
if v.GetBool(cfgEnableMetrics) {
|
||||
gateMetrics = newGateMetrics()
|
||||
}
|
||||
|
||||
return &App{
|
||||
ctr: ctr,
|
||||
log: l,
|
||||
|
@ -188,6 +200,8 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
|||
tls: tls,
|
||||
api: caller,
|
||||
|
||||
metrics: gateMetrics,
|
||||
|
||||
webDone: make(chan struct{}, 1),
|
||||
wrkDone: make(chan struct{}, 1),
|
||||
|
||||
|
@ -215,6 +229,10 @@ func (a *App) Wait() {
|
|||
zap.String("version", version.Version),
|
||||
)
|
||||
|
||||
if a.metrics != nil {
|
||||
a.metrics.SetHealth(1)
|
||||
}
|
||||
|
||||
<-a.webDone // wait for web-server to be stopped
|
||||
|
||||
a.log.Info("application finished")
|
||||
|
@ -238,7 +256,6 @@ func (a *App) Server(ctx context.Context) {
|
|||
router := newS3Router()
|
||||
|
||||
// Attach app-specific routes:
|
||||
// attachHealthy(router, a.cli)
|
||||
attachMetrics(router, a.cfg, a.log)
|
||||
attachProfiler(router, a.cfg, a.log)
|
||||
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Healthy is a health check interface.
|
||||
type Healthy interface {
|
||||
Status() error
|
||||
}
|
||||
|
||||
const (
|
||||
healthyState = "NeoFS S3 Gateway is "
|
||||
hdrContentType = "Content-Type"
|
||||
defaultContentType = "text/plain; charset=utf-8"
|
||||
namespace = "neofs_s3_gw"
|
||||
stateSubsystem = "state"
|
||||
)
|
||||
|
||||
//nolint:deadcode,unused // TODO
|
||||
func attachHealthy(r *mux.Router, h Healthy) {
|
||||
healthy := r.PathPrefix(systemPath + "/-").
|
||||
Subrouter().
|
||||
StrictSlash(true)
|
||||
|
||||
healthy.HandleFunc("/ready", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set(hdrContentType, defaultContentType)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = fmt.Fprintln(w, healthyState+"ready")
|
||||
})
|
||||
|
||||
healthy.HandleFunc("/healthy", func(w http.ResponseWriter, r *http.Request) {
|
||||
code := http.StatusOK
|
||||
msg := "healthy"
|
||||
|
||||
if err := h.Status(); err != nil {
|
||||
msg = "unhealthy: " + err.Error()
|
||||
code = http.StatusBadRequest
|
||||
type GateMetrics struct {
|
||||
stateMetrics
|
||||
}
|
||||
|
||||
w.Header().Set(hdrContentType, defaultContentType)
|
||||
w.WriteHeader(code)
|
||||
_, _ = fmt.Fprintln(w, healthyState+msg)
|
||||
})
|
||||
type stateMetrics struct {
|
||||
healthCheck prometheus.Gauge
|
||||
}
|
||||
|
||||
func newGateMetrics() *GateMetrics {
|
||||
stateMetric := newStateMetrics()
|
||||
stateMetric.register()
|
||||
|
||||
return &GateMetrics{
|
||||
stateMetrics: stateMetric,
|
||||
}
|
||||
}
|
||||
|
||||
func newStateMetrics() stateMetrics {
|
||||
return stateMetrics{
|
||||
healthCheck: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: stateSubsystem,
|
||||
Name: "health",
|
||||
Help: "Current S3 gateway state",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func (m stateMetrics) register() {
|
||||
prometheus.MustRegister(m.healthCheck)
|
||||
}
|
||||
|
||||
func (m stateMetrics) SetHealth(s int32) {
|
||||
m.healthCheck.Set(float64(s))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue