woj-server/internal/web/metrics/prometheus.go

86 lines
2.1 KiB
Go

package metrics
import (
"git.0x7f.app/WOJ/woj-server/internal/e"
"git.0x7f.app/WOJ/woj-server/internal/misc/config"
"git.0x7f.app/WOJ/woj-server/internal/pkg/cast"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
"github.com/samber/do"
)
var _ Service = (*service)(nil)
type Service interface {
Record(method, url string, success bool, httpCode int, errCode e.Status, elapsed float64)
SetLogPaths(paths []string)
Handler() gin.HandlerFunc
HealthCheck() error
}
func NewService(i *do.Injector) (Service, error) {
srv := &service{}
conf := do.MustInvoke[config.Service](i).GetConfig()
srv.setup(conf.Metrics.Namespace, conf.Metrics.Subsystem)
return srv, nil
}
type service struct {
namespace string
subsystem string
counter *prometheus.CounterVec
hist *prometheus.HistogramVec
logPaths []string
}
func (s *service) HealthCheck() error {
return nil
}
func (s *service) setup(namespace string, subsystem string) {
s.namespace = namespace
s.subsystem = subsystem
s.counter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "requests_total",
Help: "Total number of requests",
},
[]string{"method", "url"},
)
s.hist = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "requests_details",
Help: "Details of each request",
Buckets: []float64{0.01, 0.05, 0.1, 0.25, 0.5, 1, 1.5, 2, 2.5, 3, 5, 10, 15, 20, 25, 50, 75, 100, 150, 200, 500, 750, 1000, 1500, 2000},
},
[]string{"method", "url", "success", "http_code", "err_code"},
)
prometheus.MustRegister(s.counter, s.hist)
}
func (s *service) Record(method, url string, success bool, httpCode int, errCode e.Status, elapsed float64) {
s.counter.With(prometheus.Labels{
"method": method,
"url": url,
}).Inc()
s.hist.With(prometheus.Labels{
"method": method,
"url": url,
"success": cast.ToString(success),
"http_code": cast.ToString(httpCode),
"err_code": cast.ToString(errCode),
}).Observe(elapsed)
}