diff --git a/api/internal/metrics/metrics.go b/api/internal/metrics/metrics.go index c13a361b..778db4cf 100644 --- a/api/internal/metrics/metrics.go +++ b/api/internal/metrics/metrics.go @@ -4,4 +4,5 @@ const serviceName = "wormscan-api" type Metrics interface { IncExpiredCacheResponse(key string) + IncOrigin(origin, method, path string) } diff --git a/api/internal/metrics/prometheus.go b/api/internal/metrics/prometheus.go index 0146a4f5..aa59c303 100644 --- a/api/internal/metrics/prometheus.go +++ b/api/internal/metrics/prometheus.go @@ -8,22 +8,35 @@ import ( // PrometheusMetrics is a Prometheus implementation of Metric interface. type PrometheusMetrics struct { expiredCacheResponseCount *prometheus.CounterVec + originRequestsCount *prometheus.CounterVec } // NewPrometheusMetrics returns a new instance of PrometheusMetrics. func NewPrometheusMetrics(environment string) *PrometheusMetrics { + constLabels := map[string]string{ + "environment": environment, + "service": serviceName, + } + vaaTxTrackerCount := promauto.NewCounterVec( prometheus.CounterOpts{ - Name: "expired_cache_response", - Help: "Total expired cache response by key", - ConstLabels: map[string]string{ - "environment": environment, - "service": serviceName, - }, + Name: "expired_cache_response", + Help: "Total expired cache response by key", + ConstLabels: constLabels, }, []string{"key"}) + originRequestsCount := promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "http_requests_origin_requests_total", + Help: "Count all http requests by origin, method and path.", + ConstLabels: constLabels, + }, + []string{"origin", "method", "path"}, + ) + return &PrometheusMetrics{ expiredCacheResponseCount: vaaTxTrackerCount, + originRequestsCount: originRequestsCount, } } @@ -31,10 +44,15 @@ func (m *PrometheusMetrics) IncExpiredCacheResponse(key string) { m.expiredCacheResponseCount.WithLabelValues(key).Inc() } +func (m *PrometheusMetrics) IncOrigin(origin, method, path string) { + m.originRequestsCount.WithLabelValues(origin, method, path).Inc() +} + type noOpMetrics struct{} -func (s *noOpMetrics) IncExpiredCacheResponse(_ string) { -} +func (s *noOpMetrics) IncExpiredCacheResponse(_ string) {} + +func (s *noOpMetrics) IncOrigin(_, _, _ string) {} func NewNoOpMetrics() Metrics { return &noOpMetrics{} diff --git a/api/main.go b/api/main.go index 6a1d5b69..dc49b5e6 100644 --- a/api/main.go +++ b/api/main.go @@ -197,16 +197,13 @@ func main() { prometheus := fiberprometheus.NewWithLabels(labels, "http", "") prometheus.RegisterAt(app, "/metrics") app.Use(prometheus.Middleware) + app.Use(middleware.OriginMetrics(metrics)) app.Use(requestid.New()) app.Use(logger.New(logger.Config{ Format: "level=info timestamp=${time} method=${method} path=${path} latency=${latency} status${status} request_id=${locals:requestid} ip=${ips} queryParams=${queryParams}\n", Next: func(c *fiber.Ctx) bool { - path := c.Path() - if path == "/api/v1/health" || path == "/api/v1/ready" { - return true - } - return false + return middleware.IsK8sPath(c.Path()) }, })) if cfg.PprofEnabled { diff --git a/api/middleware/k8s.go b/api/middleware/k8s.go new file mode 100644 index 00000000..9be8204a --- /dev/null +++ b/api/middleware/k8s.go @@ -0,0 +1,8 @@ +package middleware + +func IsK8sPath(path string) bool { + if path == "/api/v1/health" || path == "/api/v1/ready" { + return true + } + return false +} diff --git a/api/middleware/origin_metrics.go b/api/middleware/origin_metrics.go new file mode 100644 index 00000000..1387418d --- /dev/null +++ b/api/middleware/origin_metrics.go @@ -0,0 +1,26 @@ +// package middleare contains all the middleware function to use in the API. +package middleware + +import ( + "strings" + + "github.com/gofiber/fiber/v2" + "github.com/wormhole-foundation/wormhole-explorer/api/internal/metrics" +) + +// ExtractPagination parses pagination-related query parameters. +func OriginMetrics(m metrics.Metrics) fiber.Handler { + return func(c *fiber.Ctx) error { + err := c.Next() + path := c.Route().Path + if !IsK8sPath(path) { + method := c.Route().Method + originHeader := strings.ToLower(c.Get(fiber.HeaderOrigin)) + if originHeader == "" { + originHeader = "unknown" + } + m.IncOrigin(originHeader, method, path) + } + return err + } +}