middleware/logger.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
package middleware import ( "fmt" "log" "net/http" "time" ) // customResponseWriter wraps the standard http.ResponseWriter to capture the status code type customResponseWriter struct { http.ResponseWriter statusCode int } func newCustomResponseWriter(w http.ResponseWriter) *customResponseWriter { // Default status code to 200 OK return &customResponseWriter{w, http.StatusOK} } func (rw *customResponseWriter) WriteHeader(code int) { rw.statusCode = code rw.ResponseWriter.WriteHeader(code) } // Logger middleware logs request details and uses different log levels based on the status code func Logger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Start time start := time.Now() // Wrap the ResponseWriter to capture the status code crw := newCustomResponseWriter(w) // Serve the request next.ServeHTTP(crw, r) // Determine the log level based on the status code duration := time.Since(start) statusCode := crw.statusCode // Log entry with timestamp, log level, and request details logEntry := fmt.Sprintf("%s method=%s url=%s status=%d duration=%s", getLogLevel(statusCode), r.Method, r.URL.Path, statusCode, duration, ) // Log the entry log.Println(logEntry) }) } // getLogLevel returns the log level based on the status code func getLogLevel(statusCode int) string { switch { case statusCode >= 500: return colorize("ERROR", "red") case statusCode >= 400: return colorize("WARN", "yellow") default: return colorize("INFO", "blue") } } // colorize returns the text wrapped in ANSI escape codes for coloring func colorize(text, color string) string { var colorCode string switch color { case "red": colorCode = "\033[31m" case "green": colorCode = "\033[32m" case "yellow": colorCode = "\033[33m" case "blue": colorCode = "\033[1;34m" default: colorCode = "\033[0m" // Reset color } return fmt.Sprintf("%s%s\033[0m", colorCode, text) } |