1package ext
2
3import (
4 "log/slog"
5 "net/http"
6 "time"
7)
8
9type statusWraper struct {
10 statusCode int
11 innerWriter http.ResponseWriter
12}
13
14func (s *statusWraper) Header() http.Header {
15 return s.innerWriter.Header()
16}
17
18func (s *statusWraper) Write(b []byte) (int, error) {
19 return s.innerWriter.Write(b)
20}
21
22func (s *statusWraper) WriteHeader(statusCode int) {
23 s.statusCode = statusCode
24 s.innerWriter.WriteHeader(statusCode)
25}
26
27func (s *statusWraper) StatusCode() int {
28 if s.statusCode == 0 {
29 return 200
30 }
31 return s.statusCode
32}
33
34func wrap(w http.ResponseWriter) *statusWraper {
35 return &statusWraper{
36 innerWriter: w,
37 }
38}
39
40func Log(next http.HandlerFunc) http.HandlerFunc {
41 return func(w http.ResponseWriter, r *http.Request) {
42 t := time.Now()
43 s := wrap(w)
44 next(s, r)
45 slog.Info(
46 "Http request",
47 "method", r.Method,
48 "code", s.StatusCode(),
49 "path", r.URL,
50 "elapsed", time.Since(t),
51 )
52 }
53}