Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect metrics when serving static files #1255

Merged
merged 7 commits into from
Dec 4, 2024
12 changes: 12 additions & 0 deletions pkg/gofr/http/middleware/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"

Expand All @@ -26,6 +27,17 @@ func Metrics(metrics metrics) func(inner http.Handler) http.Handler {
srw := &StatusResponseWriter{ResponseWriter: w}

path, _ := mux.CurrentRoute(r).GetPathTemplate()

ext := strings.ToLower(filepath.Ext(r.URL.Path))
switch ext {
case ".css", ".js", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg", ".txt", ".html", ".json", ".woff", ".woff2", ".ttf", ".eot", ".pdf":
path = r.URL.Path
}

if path == "/" || strings.HasPrefix(path, "/static") {
path = r.URL.Path
}

path = strings.TrimSuffix(path, "/")

// this has to be called in the end so that status code is populated
Expand Down
67 changes: 67 additions & 0 deletions pkg/gofr/http/middleware/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -54,3 +55,69 @@ func TestMetrics(t *testing.T) {
mockMetrics.AssertCalled(t, "RecordHistogram", mock.Anything, "app_http_response", mock.Anything,
[]string{"path", "/test", "method", "GET", "status", "200"})
}

func TestMetrics_StaticFile(t *testing.T) {
mockMetrics := &mockMetrics{}

mockMetrics.On("RecordHistogram", mock.Anything, "app_http_response", mock.Anything,
[]string{"path", "/static/example.js", "method", "GET", "status", "200"}).Return(nil)

// Create a temporary static file for the test
tempDir := t.TempDir()
staticFilePath := tempDir + "/example.js"

err := os.WriteFile(staticFilePath, []byte("console.log('test');"), 0600)
if err != nil {
t.Errorf("failed to create temporary static file: %v", err)
}

router := mux.NewRouter()
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(tempDir)))).Name("/static/")

router.Use(Metrics(mockMetrics))

req := httptest.NewRequest(http.MethodGet, "/static/example.js", http.NoBody)
rr := httptest.NewRecorder()

router.ServeHTTP(rr, req)

if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}

mockMetrics.AssertCalled(t, "RecordHistogram", mock.Anything, "app_http_response", mock.Anything,
[]string{"path", "/static/example.js", "method", "GET", "status", "200"})
}

func TestMetrics_StaticFileWithQueryParam(t *testing.T) {
mockMetrics := &mockMetrics{}

mockMetrics.On("RecordHistogram", mock.Anything, "app_http_response", mock.Anything,
[]string{"path", "/static/example.js", "method", "GET", "status", "200"}).Return(nil)

// Create a temporary static file for the test
tempDir := t.TempDir()
staticFilePath := tempDir + "/example.js"

err := os.WriteFile(staticFilePath, []byte("console.log('test');"), 0600)
if err != nil {
t.Errorf("failed to create temporary static file: %v", err)
}

router := mux.NewRouter()
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(tempDir)))).Name("/static/")

router.Use(Metrics(mockMetrics))

req := httptest.NewRequest(http.MethodGet, "/static/example.js?v=42", http.NoBody)
rr := httptest.NewRecorder()

router.ServeHTTP(rr, req)

if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}

mockMetrics.AssertCalled(t, "RecordHistogram", mock.Anything, "app_http_response", mock.Anything,
[]string{"path", "/static/example.js", "method", "GET", "status", "200"})
}
Loading