naco-api/internal/server/GlobalLoggingMiddleware.go
2026-08-03 11:08:53 +00:00

63 lines
1.4 KiB
Go

package server
import (
"fmt"
"net/http"
"strings"
"time"
log "github.com/nacorid/logger"
)
type statusTrackingWriter struct {
http.ResponseWriter
statusCode int
}
func (stw *statusTrackingWriter) WriteHeader(code int) {
stw.statusCode = code
stw.ResponseWriter.WriteHeader(code)
}
func (stw *statusTrackingWriter) Write(b []byte) (int, error) {
if stw.statusCode == 0 {
stw.statusCode = http.StatusOK
}
return stw.ResponseWriter.Write(b)
}
func GlobalLoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/healthz" {
next.ServeHTTP(w, r)
return
}
start := time.Now()
ipAddr := r.RemoteAddr
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
ipAddr = strings.TrimSpace(strings.Split(forwarded, ",")[0])
} else if realIP := r.Header.Get("X-Real-Ip"); realIP != "" {
ipAddr = realIP
}
stw := &statusTrackingWriter{ResponseWriter: w}
next.ServeHTTP(stw, r)
duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond))
status := stw.statusCode
if status == 0 {
status = http.StatusOK
}
log.InfoWithContext(r.Context(), "HTTP Request Processed",
"method", r.Method,
"path", r.URL.Path,
"status", status,
"duration", duration,
"remote_ip", ipAddr,
"user_agent", r.UserAgent(),
)
})
}