github.com/jalateras/up@v0.1.5/http/logs/logs.go (about) 1 // Package logs provides HTTP request and response logging. 2 package logs 3 4 import ( 5 "net/http" 6 "time" 7 8 "github.com/apex/log" 9 10 "github.com/apex/up" 11 "github.com/apex/up/internal/logs" 12 ) 13 14 // TODO: optional verbose mode with req/res header etc? 15 16 // log context. 17 var ctx = logs.Plugin("logs") 18 19 // response wrapper. 20 type response struct { 21 http.ResponseWriter 22 written int 23 code int 24 } 25 26 // Write implementation. 27 func (r *response) Write(b []byte) (int, error) { 28 n, err := r.ResponseWriter.Write(b) 29 r.written += n 30 return n, err 31 } 32 33 // WriteHeader implementation. 34 func (r *response) WriteHeader(code int) { 35 r.code = code 36 r.ResponseWriter.WriteHeader(code) 37 } 38 39 // New logs handler. 40 func New(c *up.Config, next http.Handler) (http.Handler, error) { 41 if c.Logs.Disable { 42 return next, nil 43 } 44 45 h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 46 start := time.Now() 47 res := &response{ResponseWriter: w, code: 200} 48 49 next.ServeHTTP(res, r) 50 51 c := ctx.WithFields(log.Fields{ 52 "stage": r.Header.Get("X-Stage"), 53 "id": r.Header.Get("X-Request-Id"), 54 "method": r.Method, 55 "path": r.URL.Path, 56 "query": r.URL.Query().Encode(), 57 "duration": int(time.Since(start) / time.Millisecond), 58 "size": res.written, 59 "ip": r.RemoteAddr, 60 "status": res.code, 61 }) 62 63 switch { 64 case res.code >= 500: 65 c.Error("response") 66 case res.code >= 400: 67 c.Warn("response") 68 default: 69 c.Info("response") 70 } 71 }) 72 73 return h, nil 74 }