Files
Nip-05-api/internal/http/middleware/logging.go
2026-04-29 02:35:00 +00:00

50 lines
1.0 KiB
Go

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,
)
})
}