Сделал для http запросов уровень логирования DEBUG
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
@@ -340,7 +341,9 @@ func errJSON(err error) map[string]string {
|
|||||||
return map[string]string{"error": err.Error()}
|
return map[string]string{"error": err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// requestLogger пишет структурированный лог по каждому запросу.
|
// requestLogger пишет структурированный лог по каждому запросу. Частые
|
||||||
|
// служебные запросы (healthcheck, GET-страницы веб-UI с авто-рефрешем) пишем
|
||||||
|
// на DEBUG, чтобы не зашумлять INFO; мутации и REST API остаются на INFO.
|
||||||
func requestLogger(logger *slog.Logger) func(http.Handler) http.Handler {
|
func requestLogger(logger *slog.Logger) func(http.Handler) http.Handler {
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -349,7 +352,7 @@ func requestLogger(logger *slog.Logger) func(http.Handler) http.Handler {
|
|||||||
|
|
||||||
next.ServeHTTP(ww, r)
|
next.ServeHTTP(ww, r)
|
||||||
|
|
||||||
logger.Info("http request",
|
logger.Log(r.Context(), requestLogLevel(r), "http request",
|
||||||
"method", r.Method,
|
"method", r.Method,
|
||||||
"path", r.URL.Path,
|
"path", r.URL.Path,
|
||||||
"status", ww.Status(),
|
"status", ww.Status(),
|
||||||
@@ -360,3 +363,17 @@ func requestLogger(logger *slog.Logger) func(http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requestLogLevel понижает уровень для частых служебных запросов: healthcheck
|
||||||
|
// и GET-страницы веб-UI (список авто-рефрешится каждые 5 с). Мутации и REST
|
||||||
|
// API (`/api/...`) остаются на INFO.
|
||||||
|
func requestLogLevel(r *http.Request) slog.Level {
|
||||||
|
switch {
|
||||||
|
case r.URL.Path == "/healthz":
|
||||||
|
return slog.LevelDebug
|
||||||
|
case r.Method == http.MethodGet && !strings.HasPrefix(r.URL.Path, "/api"):
|
||||||
|
return slog.LevelDebug
|
||||||
|
default:
|
||||||
|
return slog.LevelInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package httpapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRequestLogLevel(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
method, path string
|
||||||
|
want slog.Level
|
||||||
|
}{
|
||||||
|
{"GET", "/healthz", slog.LevelDebug}, // healthcheck — тихо
|
||||||
|
{"GET", "/", slog.LevelDebug}, // список (авто-рефреш)
|
||||||
|
{"GET", "/review/1", slog.LevelDebug}, // страница ревью
|
||||||
|
{"GET", "/api/downloads", slog.LevelInfo}, // REST API — на INFO
|
||||||
|
{"POST", "/ui/downloads/1/apply", slog.LevelInfo}, // мутация — на INFO
|
||||||
|
{"POST", "/api/downloads", slog.LevelInfo}, // приём — на INFO
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
r := httptest.NewRequest(c.method, c.path, nil)
|
||||||
|
if got := requestLogLevel(r); got != c.want {
|
||||||
|
t.Errorf("%s %s: level=%v, want %v", c.method, c.path, got, c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user