package logger import ( "github.com/rs/zerolog" "net/http" "time" ) // responseData contains the data from the response. type responseData struct { status int } // loggingResponseWriter is a wrapper around http.ResponseWriter that keeps track of its HTTP status code and check response data errors type loggingResponseWriter struct { http.ResponseWriter responseData *responseData } func (r *loggingResponseWriter) WriteHeader(statusCode int) { r.ResponseWriter.WriteHeader(statusCode) r.responseData.status = statusCode } // HTTPLoggerFunc create middleware that get status code and error message from response writer with Adapted logger func HTTPLoggerFunc(logger zerolog.Logger, handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() ipAddress := r.Header.Get("X-Real-Ip") if ipAddress == "" { ipAddress = r.Header.Get("X-Forwarded-For") } responseData := &responseData{} ww := loggingResponseWriter{ ResponseWriter: w, responseData: responseData, } handler.ServeHTTP(&ww, r) switch responseData.status { case 200, 201, 202, 204: logger.Info(). Dur("ms", time.Since(start)). Str("url", r.URL.String()). Str("mtd", r.Method). Int("sts", responseData.status). Str("ip", ipAddress).Send() default: logger.Error(). Dur("ms", time.Since(start)). Str("url", r.URL.String()). Int("sts", responseData.status). Str("mtd", r.Method). Str("ip", ipAddress). Str("tkn", r.Header.Get("X-API-Key")).Send() } }) }