axe/internal/middleware/accesslog.go

47 lines
1.6 KiB
Go
Raw Normal View History

2026-10-18 19:07:25 +00:00
// Package middleware — общие gin-middleware: request-id, access-log
// и восстановление после паники. Ставятся в cmd/api в таком порядке,
// где request_id идёт первым — остальные пишут его в свои записи.
package middleware
import (
"log/slog"
"time"
"github.com/gin-gonic/gin"
)
// AccessLog пишет по одной записи на запрос: метод, путь, статус,
// длительность, адрес клиента и request_id.
//
// Уровень выбирается по коду ответа: 5xx — error, 4xx — warn, остальное —
// info. Так обычный трафик не засоряет ошибки, а реальные падения видно
// фильтром уровня.
func AccessLog() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
attrs := []any{
"method", c.Request.Method,
"path", c.Request.URL.Path,
"status", c.Writer.Status(),
"duration_ms", time.Since(start).Milliseconds(),
"client_ip", c.ClientIP(),
"request_id", RequestIDFrom(c),
}
// Кто именно дёргал — важно для аудита, но не все запросы авторизованы.
if userID := c.GetString("user_id"); userID != "" {
attrs = append(attrs, "user_id", userID)
}
switch status := c.Writer.Status(); {
case status >= 500:
slog.Error("request", attrs...)
case status >= 400:
slog.Warn("request", attrs...)
default:
slog.Info("request", attrs...)
}
}
}