package handlers import ( "fmt" "net/http" "time" "github.com/dnote/dnote/pkg/server/log" ) // logResponseWriter wraps http.ResponseWriter to expose HTTP status code for logging. // The optional interfaces of http.ResponseWriter are lost because of the wrapping, and // such interfaces should be implemented if needed. (i.e. http.Pusher, http.Flusher, etc.) type logResponseWriter struct { http.ResponseWriter statusCode int } func (w *logResponseWriter) WriteHeader(code int) { w.statusCode = code w.ResponseWriter.WriteHeader(code) } // Logging is a logging middleware func Logging(inner http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() lw := logResponseWriter{w, http.StatusOK} inner.ServeHTTP(&lw, r) log.WithFields(log.Fields{ "origin": r.Header.Get("Origin"), "remoteAddr": lookupIP(r), "uri": r.RequestURI, "statusCode": lw.statusCode, "method": r.Method, "duration": fmt.Sprintf("%dms", time.Since(start)/1000000), "userAgent": r.Header.Get("User-Agent"), }).Info("incoming request") } }