[#199] Add metrics for HTTP endpoint status #201
5 changed files with 79 additions and 10 deletions
|
@ -453,6 +453,7 @@ func (a *App) Serve(ctx context.Context) {
|
|||
a.log.Info(logs.StartingServer, zap.String("address", a.servers[i].Address()))
|
||||
|
||||
if err := srv.Serve(a.servers[i].Listener()); err != nil && err != http.ErrServerClosed {
|
||||
a.metrics.MarkUnhealthy(a.servers[i].Address())
|
||||
a.log.Fatal(logs.ListenAndServe, zap.Error(err))
|
||||
}
|
||||
}(i)
|
||||
|
@ -556,9 +557,11 @@ func (a *App) initServers(ctx context.Context) {
|
|||
}
|
||||
srv, err := newServer(ctx, serverInfo)
|
||||
if err != nil {
|
||||
a.metrics.MarkUnhealthy(serverInfo.Address)
|
||||
a.log.Warn(logs.FailedToAddServer, append(fields, zap.Error(err))...)
|
||||
continue
|
||||
}
|
||||
a.metrics.MarkHealthy(serverInfo.Address)
|
||||
|
||||
a.servers = append(a.servers, srv)
|
||||
a.log.Info(logs.AddServer, fields...)
|
||||
|
|
|
@ -84,3 +84,19 @@ func (m *AppMetrics) Statistic() *APIStatMetrics {
|
|||
func (m *AppMetrics) Gather() ([]*dto.MetricFamily, error) {
|
||||
return m.gate.Gather()
|
||||
}
|
||||
|
||||
func (m *AppMetrics) MarkHealthy(endpoint string) {
|
||||
if !m.isEnabled() {
|
||||
return
|
||||
}
|
||||
|
||||
m.gate.HTTPServer.MarkHealthy(endpoint)
|
||||
}
|
||||
|
||||
func (m *AppMetrics) MarkUnhealthy(endpoint string) {
|
||||
if !m.isEnabled() {
|
||||
return
|
||||
}
|
||||
|
||||
m.gate.HTTPServer.MarkUnhealthy(endpoint)
|
||||
}
|
||||
|
|
|
@ -134,6 +134,16 @@ var appMetricsDesc = map[string]map[string]Description{
|
|||
VariableLabels: []string{"direction"},
|
||||
},
|
||||
},
|
||||
serverSubsystem: {
|
||||
httpHealthMetric: Description{
|
||||
Type: dto.MetricType_GAUGE,
|
||||
Namespace: namespace,
|
||||
Subsystem: serverSubsystem,
|
||||
Name: httpHealthMetric,
|
||||
Help: "HTTP Server endpoint health",
|
||||
dkirillov marked this conversation as resolved
Outdated
|
||||
VariableLabels: []string{"endpoint"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
|
|
|
@ -16,11 +16,12 @@ type StatisticScraper interface {
|
|||
}
|
||||
|
||||
type GateMetrics struct {
|
||||
registry prometheus.Registerer
|
||||
State *StateMetrics
|
||||
Pool *poolMetricsCollector
|
||||
Billing *billingMetrics
|
||||
Stats *APIStatMetrics
|
||||
registry prometheus.Registerer
|
||||
State *StateMetrics
|
||||
Pool *poolMetricsCollector
|
||||
Billing *billingMetrics
|
||||
Stats *APIStatMetrics
|
||||
HTTPServer *httpServerMetrics
|
||||
}
|
||||
|
||||
func NewGateMetrics(scraper StatisticScraper) *GateMetrics {
|
||||
|
@ -38,12 +39,16 @@ func NewGateMetrics(scraper StatisticScraper) *GateMetrics {
|
|||
statsMetric := newAPIStatMetrics()
|
||||
registry.MustRegister(statsMetric)
|
||||
|
||||
serverMetric := newHTTPServerMetrics()
|
||||
registry.MustRegister(serverMetric)
|
||||
|
||||
return &GateMetrics{
|
||||
registry: registry,
|
||||
State: stateMetric,
|
||||
Pool: poolMetric,
|
||||
Billing: billingMetric,
|
||||
Stats: statsMetric,
|
||||
registry: registry,
|
||||
State: stateMetric,
|
||||
Pool: poolMetric,
|
||||
Billing: billingMetric,
|
||||
Stats: statsMetric,
|
||||
HTTPServer: serverMetric,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +57,7 @@ func (g *GateMetrics) Unregister() {
|
|||
g.registry.Unregister(g.Pool)
|
||||
g.Billing.Unregister()
|
||||
g.registry.Unregister(g.Stats)
|
||||
g.registry.Unregister(g.HTTPServer)
|
||||
}
|
||||
|
||||
func (g *GateMetrics) Handler() http.Handler {
|
||||
|
|
34
metrics/http.go
Normal file
34
metrics/http.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package metrics
|
||||
|
||||
import "github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
const (
|
||||
serverSubsystem = "server"
|
||||
alexvanin
commented
Let's use Let's use `server` here too as in HTTP gateway. S3 works only through http protocol.
|
||||
httpHealthMetric = "health"
|
||||
)
|
||||
|
||||
type httpServerMetrics struct {
|
||||
endpointHealth *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
func newHTTPServerMetrics() *httpServerMetrics {
|
||||
return &httpServerMetrics{
|
||||
endpointHealth: mustNewGaugeVec(appMetricsDesc[serverSubsystem][httpHealthMetric]),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *httpServerMetrics) Collect(ch chan<- prometheus.Metric) {
|
||||
m.endpointHealth.Collect(ch)
|
||||
}
|
||||
|
||||
func (m *httpServerMetrics) Describe(desc chan<- *prometheus.Desc) {
|
||||
m.endpointHealth.Describe(desc)
|
||||
}
|
||||
|
||||
func (m *httpServerMetrics) MarkHealthy(endpoint string) {
|
||||
m.endpointHealth.WithLabelValues(endpoint).Set(float64(1))
|
||||
}
|
||||
|
||||
func (m *httpServerMetrics) MarkUnhealthy(endpoint string) {
|
||||
m.endpointHealth.WithLabelValues(endpoint).Set(float64(0))
|
||||
}
|
Loading…
Reference in a new issue
Probably we should use
S3 Server endpoint health
I thought it's name of protocol (http/grpc)