Skip to content

Commit

Permalink
fix: logging and cache middleware (#72)
Browse files Browse the repository at this point in the history
* Fix logging and cache middleware

* linter

* minor fix

* linter

* fixes

* Enhanced cache config

* linter

* minor change

* update comment
  • Loading branch information
lucaslopezf authored Feb 26, 2024
1 parent 070ffcb commit 58a3190
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 31 deletions.
37 changes: 29 additions & 8 deletions pkg/zrouter/zmiddlewares/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/zondax/golem/pkg/zcache"
"github.com/zondax/golem/pkg/zrouter/domain"
"net/http"
"regexp"
"runtime/debug"
"time"
)
Expand All @@ -14,23 +15,32 @@ const (
cacheKeyPrefix = "zrouter_cache"
)

type CacheProcessedPath struct {
Regex *regexp.Regexp
TTL time.Duration
}

func CacheMiddleware(cache zcache.ZCache, config domain.CacheConfig) func(next http.Handler) http.Handler {
processedPaths := processCachePaths(config.Paths)

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
fullURL := constructFullURL(r)

if ttl, found := config.Paths[path]; found {
key := constructCacheKey(fullURL)
for _, pPath := range processedPaths {
if pPath.Regex.MatchString(path) {
key := constructCacheKey(fullURL)

if tryServeFromCache(w, r, cache, key) {
if tryServeFromCache(w, r, cache, key) {
return
}

rw := &responseWriter{ResponseWriter: w}
next.ServeHTTP(rw, r) // Important: this line needs to be BEFORE setting the cache.
cacheResponseIfNeeded(rw, r, cache, key, pPath.TTL)
return
}

rw := &responseWriter{ResponseWriter: w}
next.ServeHTTP(rw, r) // Important: This line needs to be BEFORE setting the cache.
cacheResponseIfNeeded(rw, r, cache, key, ttl)
return
}

next.ServeHTTP(w, r)
Expand Down Expand Up @@ -89,3 +99,14 @@ func ParseCacheConfigPaths(paths map[string]string) (domain.CacheConfig, error)

return domain.CacheConfig{Paths: parsedPaths}, nil
}

func processCachePaths(paths map[string]time.Duration) []CacheProcessedPath {
var processedPaths []CacheProcessedPath
for path, ttl := range paths {
processedPaths = append(processedPaths, CacheProcessedPath{
Regex: PathToRegexp(path),
TTL: ttl,
})
}
return processedPaths
}
15 changes: 15 additions & 0 deletions pkg/zrouter/zmiddlewares/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package zmiddlewares

import (
"regexp"
"strings"
)

func PathToRegexp(path string) *regexp.Regexp {
escapedPath := regexp.QuoteMeta(path)
escapedPath = strings.ReplaceAll(escapedPath, "\\{", "{")
escapedPath = strings.ReplaceAll(escapedPath, "\\}", "}")

pattern := regexp.MustCompile(`\{[^}]*\}`).ReplaceAllString(escapedPath, "[^/]+")
return regexp.MustCompile("^" + pattern + "$")
}
4 changes: 2 additions & 2 deletions pkg/zrouter/zmiddlewares/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ func requestIDMiddleware(next http.Handler) http.Handler {
})
}

func Logger() Middleware {
return LoggingMiddleware
func Logger(options LoggingMiddlewareOptions) Middleware {
return LoggingMiddleware(options)
}
60 changes: 40 additions & 20 deletions pkg/zrouter/zmiddlewares/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,52 @@ import (
"bytes"
"github.com/zondax/golem/pkg/logger"
"net/http"
"regexp"
"time"
)

func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
buffer := &bytes.Buffer{}
type LoggingMiddlewareOptions struct {
ExcludePaths []string
}

func LoggingMiddleware(options LoggingMiddlewareOptions) func(http.Handler) http.Handler {
excludeRegexps := make([]*regexp.Regexp, len(options.ExcludePaths))
for i, path := range options.ExcludePaths {
excludeRegexps[i] = PathToRegexp(path)
}

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestPath := r.URL.Path
for _, re := range excludeRegexps {
if re.MatchString(requestPath) {
next.ServeHTTP(w, r)
return
}
}

buffer := &bytes.Buffer{}

rw := &responseWriter{
ResponseWriter: w,
body: buffer,
}
rw := &responseWriter{
ResponseWriter: w,
body: buffer,
}

start := time.Now()
next.ServeHTTP(rw, r)
duration := time.Since(start)
ctx := r.Context()
start := time.Now()
next.ServeHTTP(rw, r)
duration := time.Since(start)
ctx := r.Context()

log := logger.GetLoggerFromContext(ctx)
log := logger.GetLoggerFromContext(ctx)

if log.IsDebugEnabled() {
log.Debugf("Method: %s - URL: %s | Status: %d - Duration: %s - Response Body: %s",
r.Method, r.URL.String(), rw.status, duration, string(rw.Body()))
return
}
if log.IsDebugEnabled() {
log.Debugf("Method: %s - URL: %s | Status: %d - Duration: %s - Response Body: %s",
r.Method, r.URL.String(), rw.status, duration, string(rw.Body()))
return
}

log.Infof("Method: %s - URL: %s | Status: %d - Duration: %s",
r.Method, r.URL.String(), rw.status, duration)
})
log.Infof("Method: %s - URL: %s | Status: %d - Duration: %s",
r.Method, r.URL.String(), rw.status, duration)
})
}
}
1 change: 0 additions & 1 deletion pkg/zrouter/zrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ func (r *zrouter) SetDefaultMiddlewares() {

r.Use(zmiddlewares.RequestMetrics(r.appName, r.metricsServer))
r.Use(zmiddlewares.RequestID())
r.Use(zmiddlewares.Logger())
}

func (r *zrouter) Group(prefix string) Routes {
Expand Down

0 comments on commit 58a3190

Please sign in to comment.