From 20cc4d9bfeb6add8a5244329b1facb855c0fa9fe Mon Sep 17 00:00:00 2001 From: Petro Chaikivskyi Date: Sun, 13 Sep 2026 10:51:15 +0000 Subject: [PATCH] perf: check the log level before building log arguments Signed-off-by: Petro Chaikivskyi --- middleware/log.go | 5 +++++ middleware/log_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/middleware/log.go b/middleware/log.go index 98876d98..bb223a74 100644 --- a/middleware/log.go +++ b/middleware/log.go @@ -2,6 +2,7 @@ package middleware import ( "bufio" + "context" "io" "log/slog" "net" @@ -131,6 +132,10 @@ func (l *lm) Log(next http.Handler, accessLogs bool) http.Handler { } func (l *lm) writeLog(accessLog bool, r *http.Request, bw *wrapper, start time.Time) { + if !l.log.Enabled(context.Background(), slog.LevelInfo) { + return + } + if !accessLog { l.log.Info("http log", "status", bw.code, diff --git a/middleware/log_test.go b/middleware/log_test.go index 8b2c1735..a739f039 100644 --- a/middleware/log_test.go +++ b/middleware/log_test.go @@ -1,8 +1,13 @@ package middleware import ( + "bytes" + "io" + "log/slog" "net/http" + "net/http/httptest" "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -110,3 +115,39 @@ func TestWrapper_ResetClearsState(t *testing.T) { assert.Zero(t, w.read) assert.Zero(t, w.write) } + +func TestWriteLog_BuildsNothingWhenLevelDisabled(t *testing.T) { + l := &lm{log: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{ + Level: slog.LevelError, + }))} + + bw := &wrapper{code: http.StatusOK} + req := httptest.NewRequest(http.MethodGet, "/some/path?a=1&b=2", nil) + req.Header.Set("User-Agent", "test-agent/1.0") + req.Header.Set("Referer", "http://example.com/from") + start := time.Now() + + access := testing.AllocsPerRun(100, func() { + l.writeLog(true, req, bw, start) + }) + assert.Zero(t, access, "a discarded access-log line must allocate nothing") + + plain := testing.AllocsPerRun(100, func() { + l.writeLog(false, req, bw, start) + }) + assert.Zero(t, plain, "a discarded log line must allocate nothing") +} + +func TestWriteLog_EmittedWhenLevelEnabled(t *testing.T) { + var buf bytes.Buffer + l := &lm{log: slog.New(slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelInfo}))} + + bw := &wrapper{code: http.StatusOK, read: 3, write: 7} + req := httptest.NewRequest(http.MethodGet, "/some/path", nil) + + l.writeLog(false, req, bw, time.Now()) + + assert.Contains(t, buf.String(), "http log") + assert.Contains(t, buf.String(), "read_bytes=3") + assert.Contains(t, buf.String(), "write_bytes=7") +}