-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.go
90 lines (74 loc) · 1.96 KB
/
middleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package charmlogfiber
import (
"net/http"
"time"
"github.com/charmbracelet/log"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
type Config struct {
DefaultLevel log.Level
ClientErrorLevel log.Level
ServerErrorLevel log.Level
WithRequestID bool
}
// New returns a fiber.Handler (middleware) that logs requests using slog.
//
// Requests with errors are logged using slog.Error().
// Requests without errors are logged using slog.Info().
func New(logger *log.Logger) fiber.Handler {
return NewWithConfig(logger, Config{
DefaultLevel: log.InfoLevel,
ClientErrorLevel: log.WarnLevel,
ServerErrorLevel: log.ErrorLevel,
WithRequestID: true,
})
}
// NewWithConfig returns a fiber.Handler (middleware) that logs requests using slog.
func NewWithConfig(logger *log.Logger, config Config) fiber.Handler {
return func(c *fiber.Ctx) error {
c.Path()
start := time.Now()
path := c.Path()
requestID := uuid.New().String()
if config.WithRequestID {
c.Context().SetUserValue("request-id", requestID)
c.Set("X-Request-ID", requestID)
}
err := c.Next()
end := time.Now()
latency := end.Sub(start)
attributes := []interface{}{
"status", c.Response().StatusCode(),
"method", string(c.Context().Method()),
"path", path,
"ip", c.Context().RemoteIP().String(),
"latency", latency,
"user-agent", string(c.Context().UserAgent()),
"time", end,
}
if config.WithRequestID {
attributes = append(attributes, "request-id", requestID)
}
switch {
case c.Response().StatusCode() >= http.StatusBadRequest:
if err != nil {
attributes = append(attributes, "error", err)
}
logger.Error("Incoming request with error",
attributes...,
)
default:
logger.Info("Incoming request", attributes...)
}
return err
}
}
// GetRequestID returns the request identifier
func GetRequestID(c *fiber.Ctx) string {
requestID, ok := c.Context().UserValue("request-id").(string)
if !ok {
return ""
}
return requestID
}