package middleware import ( "bytes" "encoding/json" "fmt" "io" "log/slog" "time" "github.com/gin-gonic/gin" ) func GinLogger() gin.HandlerFunc { return func(c *gin.Context) { var body []byte if c.Request.Body != nil { body, _ = io.ReadAll(c.Request.Body) c.Request.Body = io.NopCloser(bytes.NewBuffer(body)) } headerJSON, _ := json.Marshal(c.Request.Header) startTime := time.Now() c.Next() ctx := c.Request.Context() var errorMessage string if len(c.Errors) > 0 { errorMessage = c.Errors.String() } fields := []any{ "status", c.Writer.Status(), "method", c.Request.Method, "uri", c.Request.RequestURI, "ip", c.ClientIP(), "latency", time.Since(startTime).String(), "user_agent", c.Request.UserAgent(), "headers", string(headerJSON), "request_body", string(body), "errors", errorMessage, } status := c.Writer.Status() if len(c.Errors) > 0 || status >= 500 { slog.ErrorContext(ctx, fmt.Sprintf("%d %s %s", c.Writer.Status(), c.Request.Method, c.Request.RequestURI), fields...) } else if status >= 400 { slog.WarnContext(ctx, fmt.Sprintf("%d %s %s", c.Writer.Status(), c.Request.Method, c.Request.RequestURI), fields...) } else { slog.InfoContext(ctx, fmt.Sprintf("%d %s %s", c.Writer.Status(), c.Request.Method, c.Request.RequestURI), fields...) } } }