50 lines
1.3 KiB
Go
50 lines
1.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// RequestIDKey is the context key for the request ID
|
|
type requestIDKey struct{}
|
|
|
|
// RequestIDHeader is the header key for the request ID
|
|
const RequestIDHeader = "X-Request-ID"
|
|
|
|
// RequestID middleware generates a unique ID for each request
|
|
func RequestID() Middleware {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Check if request already has an ID
|
|
requestID := r.Header.Get(RequestIDHeader)
|
|
if requestID == "" {
|
|
// Generate a new UUID if none exists
|
|
requestID = uuid.New().String()
|
|
}
|
|
|
|
// Add the request ID to the response headers
|
|
w.Header().Set(RequestIDHeader, requestID)
|
|
|
|
// Store the request ID in the request context
|
|
ctx := context.WithValue(r.Context(), requestIDKey{}, requestID)
|
|
|
|
// Log the request with its ID
|
|
log.Printf("[%s] %s %s", requestID, r.Method, r.URL.Path)
|
|
|
|
// Call the next handler with the updated context
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
}
|
|
|
|
// GetRequestID retrieves the request ID from the context
|
|
func GetRequestID(ctx context.Context) string {
|
|
id, ok := ctx.Value(requestIDKey{}).(string)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return id
|
|
} |