Files
tp/main_dc/yalarba/api_yal/internal/middleware/logging.go
T
valitovgaziz 75b2f3f6b2 On branch main
modified:   main_dc/yalarba/api_yal/internal/domain/account/dto.go
	new file:   main_dc/yalarba/api_yal/internal/domain/account/errors.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/handler.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/router.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/service.go
	new file:   main_dc/yalarba/api_yal/internal/domain/account/types.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/admin.go
	modified:   main_dc/yalarba/api_yal/internal/middleware/auth.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/context.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/logging.go
	modified:   main_dc/yalarba/api_yal/internal/router/router.go
last but not yet commit
2026-03-31 09:43:18 +05:00

68 lines
1.9 KiB
Go

package middleware
import (
"bytes"
"io"
"net/http"
"time"
"api_yal/internal/logger"
"github.com/go-chi/chi/v5/middleware"
"go.uber.org/zap"
)
// RequestLoggerMiddleware логирует все HTTP запросы
func RequestLoggerMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
start := time.Now()
// Создаем кастомный ResponseWriter для захвата статуса
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
// Логируем тело запроса только для определенных методов (опционально)
var body []byte
if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
body, _ = io.ReadAll(r.Body)
r.Body = io.NopCloser(bytes.NewBuffer(body))
}
// Обрабатываем запрос
next.ServeHTTP(ww, r)
// Логируем результат
duration := time.Since(start)
logFields := []zap.Field{
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.Int("status", ww.Status()),
zap.Duration("duration", duration),
zap.String("remote_addr", r.RemoteAddr),
zap.String("user_agent", r.UserAgent()),
}
// Добавляем ID пользователя, если есть
if userID, ok := GetUserID(r.Context()); ok {
logFields = append(logFields, zap.Uint("user_id", userID))
}
// Логируем тело запроса для ошибок
if ww.Status() >= 400 && len(body) > 0 {
logFields = append(logFields, zap.ByteString("request_body", body))
}
// Выбираем уровень логирования в зависимости от статуса
switch {
case ww.Status() >= 500:
l.Error("Request failed", logFields...)
case ww.Status() >= 400:
l.Warn("Request error", logFields...)
default:
l.Info("Request completed", logFields...)
}
})
}