Add metrics collector for HTTP status codes

This commit is contained in:
Ingo Oppermann
2023-09-29 17:18:59 +02:00
parent 40495e5ef0
commit 5b81e6e23f
5 changed files with 98 additions and 6 deletions

View File

@@ -1558,6 +1558,9 @@ func (a *api) start(ctx context.Context) error {
a.sidecarserver.Handler = autocertManager.HTTPChallengeHandler(sidecarserverhandler)
}
metrics.Register(monitor.NewHTTPCollector("HTTPS", mainserverhandler))
metrics.Register(monitor.NewHTTPCollector("HTTP", sidecarserverhandler))
wgStart.Add(1)
a.wgStop.Add(1)
@@ -1583,6 +1586,8 @@ func (a *api) start(ctx context.Context) error {
sendError(err)
}()
} else {
metrics.Register(monitor.NewHTTPCollector("HTTP", mainserverhandler))
}
if a.rtmpserver != nil {

View File

@@ -16,11 +16,13 @@ type Config struct {
// Skipper defines a function to skip middleware.
Skipper middleware.Skipper
Logger log.Logger
Status func(code int)
}
var DefaultConfig = Config{
Skipper: middleware.DefaultSkipper,
Logger: log.New("HTTP"),
Logger: log.New(""),
Status: nil,
}
func New() echo.MiddlewareFunc {
@@ -76,6 +78,10 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
latency := time.Since(start)
if config.Status != nil {
config.Status(res.Status)
}
if raw != "" {
path = path + "?" + raw
}

View File

@@ -32,6 +32,7 @@ import (
"fmt"
"net/http"
"strings"
"sync"
"github.com/datarhei/core/v16/cluster"
cfgstore "github.com/datarhei/core/v16/config/store"
@@ -43,6 +44,7 @@ import (
api "github.com/datarhei/core/v16/http/handler/api"
httplog "github.com/datarhei/core/v16/http/log"
"github.com/datarhei/core/v16/http/router"
serverhandler "github.com/datarhei/core/v16/http/server"
"github.com/datarhei/core/v16/http/validator"
"github.com/datarhei/core/v16/iam"
"github.com/datarhei/core/v16/log"
@@ -104,10 +106,6 @@ type CorsConfig struct {
Origins []string
}
type Server interface {
ServeHTTP(w http.ResponseWriter, r *http.Request)
}
type server struct {
logger log.Logger
@@ -154,6 +152,11 @@ type server struct {
profiling bool
readOnly bool
metrics struct {
lock sync.Mutex
status map[int]uint64
}
}
type filesystem struct {
@@ -164,7 +167,7 @@ type filesystem struct {
middleware echo.MiddlewareFunc
}
func NewServer(config Config) (Server, error) {
func NewServer(config Config) (serverhandler.Server, error) {
s := &server{
logger: config.Logger,
mimeTypesFile: config.MimeTypesFile,
@@ -172,6 +175,8 @@ func NewServer(config Config) (Server, error) {
readOnly: config.ReadOnly,
}
s.metrics.status = map[int]uint64{}
s.filesystems = map[string]*filesystem{}
corsPrefixes := map[string][]string{
@@ -327,6 +332,12 @@ func NewServer(config Config) (Server, error) {
s.middleware.log = mwlog.NewWithConfig(mwlog.Config{
Logger: s.logger,
Status: func(code int) {
s.metrics.lock.Lock()
defer s.metrics.lock.Unlock()
s.metrics.status[code]++
},
})
s.v3handler.widget = api.NewWidget(api.WidgetConfig{
@@ -458,6 +469,19 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.router.ServeHTTP(w, r)
}
func (s *server) HTTPStatus() map[int]uint64 {
status := map[int]uint64{}
s.metrics.lock.Lock()
defer s.metrics.lock.Unlock()
for code, value := range s.metrics.status {
status[code] = value
}
return status
}
func (s *server) setRoutes() {
gzipMiddleware := mwgzip.NewWithConfig(mwgzip.Config{
Level: mwgzip.BestSpeed,

8
http/server/server.go Normal file
View File

@@ -0,0 +1,8 @@
package server
import "net/http"
type Server interface {
ServeHTTP(w http.ResponseWriter, r *http.Request)
HTTPStatus() map[int]uint64
}

49
monitor/http.go Normal file
View File

@@ -0,0 +1,49 @@
package monitor
import (
"strconv"
"github.com/datarhei/core/v16/http/server"
"github.com/datarhei/core/v16/monitor/metric"
)
type httpCollector struct {
handler server.Server
name string
statusDescr *metric.Description
}
func NewHTTPCollector(name string, handler server.Server) metric.Collector {
c := &httpCollector{
handler: handler,
name: name,
}
c.statusDescr = metric.NewDesc("http_status", "Total return status", []string{"name", "code"})
return c
}
func (c *httpCollector) Prefix() string {
return "filesystem"
}
func (c *httpCollector) Describe() []*metric.Description {
return []*metric.Description{
c.statusDescr,
}
}
func (c *httpCollector) Collect() metric.Metrics {
status := c.handler.HTTPStatus()
metrics := metric.NewMetrics()
for code, count := range status {
metrics.Add(metric.NewValue(c.statusDescr, float64(count), c.name, strconv.Itoa(code)))
}
return metrics
}
func (c *httpCollector) Stop() {}