84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// LoggingMiddleware логирует входящие HTTP-запросы
|
|
func LoggingMiddleware(logger *log.Logger) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
|
|
// Логируем основные параметры запроса
|
|
logData := map[string]interface{}{
|
|
"method": r.Method,
|
|
"path": r.URL.Path,
|
|
"query": r.URL.RawQuery,
|
|
"ip": r.RemoteAddr,
|
|
}
|
|
|
|
// Чтение тела запроса (для логирования)
|
|
var bodyBytes []byte
|
|
if r.Body != nil {
|
|
bodyBytes, _ = io.ReadAll(r.Body)
|
|
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
|
|
|
if len(bodyBytes) > 0 {
|
|
logData["body_size"] = len(bodyBytes)
|
|
// Для JSON-запросов логируем тело
|
|
if r.Header.Get("Content-Type") == "application/json" {
|
|
logData["body"] = string(bodyBytes)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Перехват ответа
|
|
rw := &responseWriter{ResponseWriter: w, status: http.StatusOK}
|
|
|
|
// Обработка запроса
|
|
next.ServeHTTP(rw, r)
|
|
|
|
// Дополняем данные для логирования
|
|
duration := time.Since(start)
|
|
logData["status"] = rw.status
|
|
logData["duration"] = duration.String()
|
|
logData["response_size"] = rw.size
|
|
|
|
// Форматированный вывод лога
|
|
logger.Printf(
|
|
"%s %s %d %s | IP: %s | Duration: %s | Body: %d bytes",
|
|
r.Method,
|
|
r.URL.Path,
|
|
rw.status,
|
|
http.StatusText(rw.status),
|
|
r.RemoteAddr,
|
|
duration,
|
|
len(bodyBytes),
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Кастомный responseWriter для перехвата статуса и размера ответа
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
size int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(code int) {
|
|
rw.status = code
|
|
rw.ResponseWriter.WriteHeader(code)
|
|
}
|
|
|
|
func (rw *responseWriter) Write(b []byte) (int, error) {
|
|
size, err := rw.ResponseWriter.Write(b)
|
|
rw.size += size
|
|
return size, err
|
|
}
|