package server import ( "log/slog" "net/http" "time" ) func (s *Server) loggingHandler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if s.logger == nil { next.ServeHTTP(w, r) return } start := time.Now() lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK} s.logger.Debug("HTTP request", slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.String("remote_addr", r.RemoteAddr), slog.String("user_agent", r.UserAgent()), ) next.ServeHTTP(lrw, r) duration := time.Since(start) s.logger.Debug("HTTP response", slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.Int("status", lrw.statusCode), slog.Duration("duration", duration), slog.String("remote_addr", r.RemoteAddr), slog.String("user_agent", r.UserAgent()), ) }) } type loggingResponseWriter struct { http.ResponseWriter statusCode int } func (lrw *loggingResponseWriter) WriteHeader(code int) { lrw.statusCode = code lrw.ResponseWriter.WriteHeader(code) } func (lrw *loggingResponseWriter) Unwrap() http.ResponseWriter { return lrw.ResponseWriter }