request_logger.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package middleware
  2. import (
  3. "bufio"
  4. "errors"
  5. "net"
  6. "net/http"
  7. "time"
  8. "github.com/porter-dev/porter/pkg/logger"
  9. )
  10. type requestLoggerResponseWriter struct {
  11. http.ResponseWriter
  12. statusCode int
  13. }
  14. func newRequestLoggerResponseWriter(w http.ResponseWriter) *requestLoggerResponseWriter {
  15. return &requestLoggerResponseWriter{w, http.StatusOK}
  16. }
  17. func (rw *requestLoggerResponseWriter) WriteHeader(code int) {
  18. rw.statusCode = code
  19. rw.ResponseWriter.WriteHeader(code)
  20. }
  21. func (rw *requestLoggerResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  22. h, ok := rw.ResponseWriter.(http.Hijacker)
  23. if !ok {
  24. return nil, nil, errors.New("ResponseWriter Interface does not support hijacking")
  25. }
  26. return h.Hijack()
  27. }
  28. type RequestLoggerMiddleware struct {
  29. logger *logger.Logger
  30. }
  31. func NewRequestLoggerMiddleware(logger *logger.Logger) *RequestLoggerMiddleware {
  32. return &RequestLoggerMiddleware{logger}
  33. }
  34. func (mw *RequestLoggerMiddleware) Middleware(next http.Handler) http.Handler {
  35. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  36. start := time.Now()
  37. rw := newRequestLoggerResponseWriter(w)
  38. next.ServeHTTP(rw, r)
  39. latency := time.Since(start)
  40. event := mw.logger.Info().Dur("latency", latency).Int("status", rw.statusCode)
  41. logger.AddLoggingContextScopes(r.Context(), event)
  42. logger.AddLoggingRequestMeta(r, event)
  43. event.Send()
  44. })
  45. }