Files
SEEN/backend/internal/middleware/request_id.go
T
2026-04-10 12:06:24 +02:00

65 lines
1.3 KiB
Go

package middleware
import (
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"
)
const requestIDHeader = "X-Request-ID"
func RequestID() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := c.GetHeader(requestIDHeader)
if requestID == "" {
requestID = uuid.NewString()
}
c.Set("request_id", requestID)
c.Header(requestIDHeader, requestID)
c.Next()
}
}
func AccessLog(log *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
requestID, _ := c.Get("request_id")
log.Info("request",
zap.String("method", c.Request.Method),
zap.String("path", c.FullPath()),
zap.Int("status", c.Writer.Status()),
zap.Duration("duration", time.Since(start)),
zap.String("client_ip", c.ClientIP()),
zap.String("request_id", toString(requestID)),
)
}
}
func Recovery(log *zap.Logger) gin.HandlerFunc {
return gin.CustomRecovery(func(c *gin.Context, recovered any) {
requestID, _ := c.Get("request_id")
log.Error("panic recovered",
zap.Any("panic", recovered),
zap.String("request_id", toString(requestID)),
)
c.AbortWithStatusJSON(500, gin.H{
"error": "internal server error",
"requestId": toString(requestID),
})
})
}
func toString(value any) string {
typed, ok := value.(string)
if !ok {
return ""
}
return typed
}