middleware.go•1.35 kB
package http
import (
"bufio"
"net"
"net/http"
"time"
"k8s.io/klog/v2"
)
func RequestMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/healthz" {
next.ServeHTTP(w, r)
return
}
start := time.Now()
lrw := &loggingResponseWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
}
next.ServeHTTP(lrw, r)
duration := time.Since(start)
klog.V(5).Infof("%s %s %d %v", r.Method, r.URL.Path, lrw.statusCode, duration)
})
}
type loggingResponseWriter struct {
http.ResponseWriter
statusCode int
headerWritten bool
}
func (lrw *loggingResponseWriter) WriteHeader(code int) {
if !lrw.headerWritten {
lrw.statusCode = code
lrw.headerWritten = true
lrw.ResponseWriter.WriteHeader(code)
}
}
func (lrw *loggingResponseWriter) Write(b []byte) (int, error) {
if !lrw.headerWritten {
lrw.statusCode = http.StatusOK
lrw.headerWritten = true
}
return lrw.ResponseWriter.Write(b)
}
func (lrw *loggingResponseWriter) Flush() {
if flusher, ok := lrw.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
}
}
func (lrw *loggingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if hijacker, ok := lrw.ResponseWriter.(http.Hijacker); ok {
return hijacker.Hijack()
}
return nil, nil, http.ErrNotSupported
}