package middleware import ( "bytes" "io" "log/slog" "net/http" ) func RequestLogger(logger *slog.Logger) func(handler http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { buff := &bytes.Buffer{} req := r.Clone(r.Context()) req.Body = io.NopCloser(io.TeeReader(r.Body, buff)) rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} next.ServeHTTP(rw, req) logger.With("request", buff.String(), "response", rw.responseBody).Debug("http request") }) } } type responseWriter struct { http.ResponseWriter statusCode int responseBody string } func (rw *responseWriter) WriteHeader(statusCode int) { rw.statusCode = statusCode rw.ResponseWriter.WriteHeader(statusCode) } func (rw *responseWriter) Write(b []byte) (int, error) { rw.responseBody = string(b) // You may want to capture only part of the response or use a different method return rw.ResponseWriter.Write(b) }