Skip to content

Commit

Permalink
feat(SQS): prometheus metrics for cache hits and misses (#7138) (#7168)
Browse files Browse the repository at this point in the history
* feat(SQS): prometheus metrics for cache hits and misses

* lint

(cherry picked from commit f6777d6)

Co-authored-by: Roman <[email protected]>
  • Loading branch information
mergify[bot] and p0mvn authored Dec 20, 2023
1 parent 3064d9e commit 7ced101
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
36 changes: 36 additions & 0 deletions ingest/sqs/domain/url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package domain

import (
"context"
"net/url"

"github.com/labstack/echo"
)

// RequestPathKeyType is a custom type for request path key.
type RequestPathKeyType string

const (
// RequestPathCtxKey is the key used to store the request path in the request context
RequestPathCtxKey RequestPathKeyType = "request_path"
)

// ParseURLPath parses the URL path from the echo context
func ParseURLPath(c echo.Context) (string, error) {
parsedURL, err := url.Parse(c.Request().RequestURI)
if err != nil {
return "", err
}

return parsedURL.Path, nil
}

// GetURLPathFromContext returns the request path from the context
func GetURLPathFromContext(ctx context.Context) (string, error) {
// Get request path for metrics
requestPath, ok := ctx.Value(RequestPathCtxKey).(string)
if !ok || (ok && len(requestPath) == 0) {
requestPath = "unknown"
}
return requestPath, nil
}
16 changes: 11 additions & 5 deletions ingest/sqs/middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package middleware

import (
"net/url"
"context"
"time"

"github.com/labstack/echo"
"github.com/prometheus/client_golang/prometheus"

"github.com/osmosis-labs/osmosis/v21/ingest/sqs/domain"
)

// GoMiddleware represent the data-struct for middleware
Expand Down Expand Up @@ -57,17 +59,21 @@ func (m *GoMiddleware) InstrumentMiddleware(next echo.HandlerFunc) echo.HandlerF
return func(c echo.Context) error {
start := time.Now()

parsedURL, err := url.Parse(c.Request().RequestURI)
requestMethod := c.Request().Method
requestPath, err := domain.ParseURLPath(c)
if err != nil {
return err
}

requestMethod := c.Request().Method
requestPath := parsedURL.Path

// Increment the request counter
requestsTotal.WithLabelValues(requestMethod, requestPath).Inc()

// Insert the request path into the context
ctx := c.Request().Context()
ctx = context.WithValue(ctx, domain.RequestPathCtxKey, requestPath)
request := c.Request().WithContext(ctx)
c.SetRequest(request)

err = next(c)

duration := time.Since(start).Seconds()
Expand Down
52 changes: 51 additions & 1 deletion ingest/sqs/router/usecase/router_usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/zap"

"github.com/osmosis-labs/osmosis/osmomath"
Expand All @@ -31,6 +32,33 @@ type routerUseCaseImpl struct {
rankedRouteCache *cache.Cache
}

const (
candidateRouteCacheLabel = "candidate_route"
rankedRouteCacheLabel = "ranked_route"
)

var (
cacheHits = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "sqs_cache_hits_total",
Help: "Total number of cache hits",
},
[]string{"route", "cache_type", "token_in", "token_out"},
)
cacheMisses = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "sqs_cache_misses_total",
Help: "Total number of cache misses",
},
[]string{"route", "cache_type", "token_in", "token_out"},
)
)

func init() {
prometheus.MustRegister(cacheHits)
prometheus.MustRegister(cacheMisses)
}

// NewRouterUsecase will create a new pools use case object
func NewRouterUsecase(timeout time.Duration, routerRepository mvc.RouterRepository, poolsUsecase mvc.PoolsUsecase, config domain.RouterConfig, logger log.Logger, rankedRouteCache *cache.Cache) mvc.RouterUsecase {
return &routerUseCaseImpl{
Expand All @@ -54,7 +82,6 @@ func NewRouterUsecase(timeout time.Duration, routerRepository mvc.RouterReposito
// Returns error if:
// - fails to estimate direct quotes for ranked routes
// - fails to retrieve candidate routes
// -
func (r *routerUseCaseImpl) GetOptimalQuote(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string) (domain.Quote, error) {
// Get an order of magnitude for the token in amount
// This is used for caching ranked routes as these might differ depending on the amount swapped in.
Expand All @@ -70,7 +97,16 @@ func (r *routerUseCaseImpl) GetOptimalQuote(ctx context.Context, tokenIn sdk.Coi

router := r.initializeRouter()

// Get request path for metrics
requestURLPath, err := domain.GetURLPathFromContext(ctx)
if err != nil {
return nil, err
}

if hasRankedRoutesInCache {
// Increase cache hits
cacheHits.WithLabelValues(requestURLPath, rankedRouteCacheLabel, tokenIn.Denom, tokenOutDenom).Inc()

rankedCandidateRoutes, ok := rankedRoutesData.(route.CandidateRoutes)
if !ok {
return nil, fmt.Errorf("error casting ranked routes from cache")
Expand All @@ -82,6 +118,9 @@ func (r *routerUseCaseImpl) GetOptimalQuote(ctx context.Context, tokenIn sdk.Coi
return nil, err
}
} else {
// Increase cache misses
cacheMisses.WithLabelValues(requestURLPath, rankedRouteCacheLabel, tokenIn.Denom, tokenOutDenom).Inc()

// If top routes are not present in cache, retrieve unranked candidate routes
candidateRoutes, err := r.handleCandidateRoutes(ctx, router, tokenIn.Denom, tokenOutDenom)
if err != nil {
Expand Down Expand Up @@ -443,8 +482,17 @@ func (r *routerUseCaseImpl) handleCandidateRoutes(ctx context.Context, router *R

r.logger.Debug("cached routes", zap.Int("num_routes", len(candidateRoutes.Routes)))

// Get request path for metrics
requestURLPath, err := domain.GetURLPathFromContext(ctx)
if err != nil {
return route.CandidateRoutes{}, err
}

// If no routes are cached, find them
if len(candidateRoutes.Routes) == 0 {
// Increase cache misses
cacheMisses.WithLabelValues(requestURLPath, candidateRouteCacheLabel, tokenInDenom, tokenOutDenom).Inc()

r.logger.Debug("calculating routes")
allPools, err := r.poolsUsecase.GetAllPools(ctx)
if err != nil {
Expand All @@ -467,6 +515,8 @@ func (r *routerUseCaseImpl) handleCandidateRoutes(ctx context.Context, router *R
return route.CandidateRoutes{}, err
}
}
} else {
cacheHits.WithLabelValues(requestURLPath, candidateRouteCacheLabel, tokenInDenom, tokenOutDenom).Inc()
}

return candidateRoutes, nil
Expand Down

0 comments on commit 7ced101

Please sign in to comment.