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.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 25, 50, 100, 250, 500, 1000}, }, []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) }