package middleware import ( "crypto/rand" "encoding/hex" "log/slog" "net/http" "time" applog "github.com/noderunners/nip05api/internal/log" ) type statusRecorder struct { http.ResponseWriter status int } func (s *statusRecorder) WriteHeader(code int) { s.status = code s.ResponseWriter.WriteHeader(code) } func newRequestID() string { b := make([]byte, 8) _, _ = rand.Read(b) return hex.EncodeToString(b) } func Logging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { id := r.Header.Get("X-Request-ID") if id == "" { id = newRequestID() } w.Header().Set("X-Request-ID", id) ctx := applog.WithRequestID(r.Context(), id) rec := &statusRecorder{ResponseWriter: w, status: 200} start := time.Now() next.ServeHTTP(rec, r.WithContext(ctx)) slog.Info("http", "request_id", id, "method", r.Method, "path", r.URL.Path, "status", rec.status, "duration_ms", time.Since(start).Milliseconds(), "remote", r.RemoteAddr, ) }) }