summaryrefslogtreecommitdiff
path: root/middleware
diff options
context:
space:
mode:
authorAlexander <a.kiryukhin@vk.team>2024-06-11 14:12:30 +0300
committerAlexander <a.kiryukhin@vk.team>2024-06-11 14:12:30 +0300
commit88a6b1cb628e4e334068e861ac5fb56274d88845 (patch)
tree312f2a3a7182b6e2fc45e87ec71ddde9861c77f8 /middleware
InitialHEADmaster
Diffstat (limited to 'middleware')
-rw-r--r--middleware/logger.go29
-rw-r--r--middleware/recover.go34
-rw-r--r--middleware/request_id.go40
-rw-r--r--middleware/use.go13
4 files changed, 116 insertions, 0 deletions
diff --git a/middleware/logger.go b/middleware/logger.go
new file mode 100644
index 0000000..039bd19
--- /dev/null
+++ b/middleware/logger.go
@@ -0,0 +1,29 @@
+package middleware
+
+import (
+ "net/http"
+
+ "log/slog"
+)
+
+func Logger(logger *slog.Logger) Middleware {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ next.ServeHTTP(w, r)
+ requestID := GetRequestID(r)
+ args := []any{
+ slog.String("proto", r.Proto),
+ slog.String("method", r.Method),
+ slog.String("request_uri", r.RequestURI),
+ }
+ if requestID != "" {
+ args = append(args, slog.String("request_id", requestID))
+ }
+ logger.InfoContext(
+ r.Context(),
+ "request",
+ args...,
+ )
+ })
+ }
+}
diff --git a/middleware/recover.go b/middleware/recover.go
new file mode 100644
index 0000000..6b5f2cb
--- /dev/null
+++ b/middleware/recover.go
@@ -0,0 +1,34 @@
+package middleware
+
+import (
+ "net/http"
+ "runtime/debug"
+
+ "log/slog"
+)
+
+func Recover(logger *slog.Logger) Middleware {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ defer func() {
+ err := recover()
+ if err == nil {
+ return
+ }
+ debug.PrintStack()
+ requestID := GetRequestID(r)
+ logger.ErrorContext(
+ r.Context(),
+ "panic",
+ slog.Any("panic", err),
+ slog.String("proto", r.Proto),
+ slog.String("method", r.Method),
+ slog.String("request_uri", r.RequestURI),
+ slog.String("request_id", requestID),
+ )
+ }()
+
+ next.ServeHTTP(w, r)
+ })
+ }
+}
diff --git a/middleware/request_id.go b/middleware/request_id.go
new file mode 100644
index 0000000..0e9a521
--- /dev/null
+++ b/middleware/request_id.go
@@ -0,0 +1,40 @@
+package middleware
+
+import (
+ "context"
+ "net/http"
+
+ "go.neonxp.ru/objectid"
+)
+
+type ctxKeyRequestID int
+
+const (
+ RequestIDKey ctxKeyRequestID = 0
+ RequestIDHeader string = "X-Request-ID"
+)
+
+func RequestID(next http.Handler) http.Handler {
+ objectid.Seed()
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ requestID := r.Header.Get(RequestIDHeader)
+ if requestID == "" {
+ requestID = objectid.New().String()
+ }
+
+ next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), RequestIDKey, requestID)))
+ })
+}
+
+func GetRequestID(r *http.Request) string {
+ rid := r.Context().Value(RequestIDKey)
+ if rid == nil {
+ return ""
+ }
+ srid, ok := rid.(string)
+ if !ok {
+ return ""
+ }
+
+ return srid
+}
diff --git a/middleware/use.go b/middleware/use.go
new file mode 100644
index 0000000..6610e2f
--- /dev/null
+++ b/middleware/use.go
@@ -0,0 +1,13 @@
+package middleware
+
+import "net/http"
+
+type Middleware func(http.Handler) http.Handler
+
+func Use(handler http.Handler, middlewares ...Middleware) http.Handler {
+ for _, h := range middlewares {
+ handler = h(handler)
+ }
+
+ return handler
+}