1package server
2
3import (
4 "log/slog"
5 "net/http"
6 "time"
7)
8
9func (s *Server) loggingHandler(next http.Handler) http.Handler {
10 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 if s.logger == nil {
12 next.ServeHTTP(w, r)
13 return
14 }
15
16 start := time.Now()
17 lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
18 s.logger.Debug(
19 "HTTP request",
20 slog.String("method", r.Method),
21 slog.String("path", r.URL.Path),
22 slog.String("remote_addr", r.RemoteAddr),
23 slog.String("user_agent", r.UserAgent()),
24 )
25
26 next.ServeHTTP(lrw, r)
27 duration := time.Since(start)
28
29 s.logger.Debug(
30 "HTTP response",
31 slog.String("method", r.Method),
32 slog.String("path", r.URL.Path),
33 slog.Int("status", lrw.statusCode),
34 slog.Duration("duration", duration),
35 slog.String("remote_addr", r.RemoteAddr),
36 slog.String("user_agent", r.UserAgent()),
37 )
38 })
39}
40
41type loggingResponseWriter struct {
42 http.ResponseWriter
43 statusCode int
44}
45
46func (lrw *loggingResponseWriter) WriteHeader(code int) {
47 lrw.statusCode = code
48 lrw.ResponseWriter.WriteHeader(code)
49}
50
51func (lrw *loggingResponseWriter) Unwrap() http.ResponseWriter {
52 return lrw.ResponseWriter
53}