Skip to content

Instantly share code, notes, and snippets.

@iancharters
Created November 3, 2023 18:00
Show Gist options
  • Save iancharters/5e9fe19c3212ccab6bae3c3985bab799 to your computer and use it in GitHub Desktop.
Save iancharters/5e9fe19c3212ccab6bae3c3985bab799 to your computer and use it in GitHub Desktop.
A logging middleware that captures response, code and duration of call
package main
import (
"bytes"
"io"
"log"
"net/http"
"time"
)
type customResponseWriter struct {
http.ResponseWriter
statusCode int
}
func (crw *customResponseWriter) WriteHeader(code int) {
crw.statusCode = code
crw.ResponseWriter.WriteHeader(code)
}
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Start the timer
start := time.Now()
// Create a buffer to capture the response
buffer := &bytes.Buffer{}
// Create a custom response writer
crw := &customResponseWriter{ResponseWriter: w}
// Create a multiwriter to write to both the response and the buffer
multi := io.MultiWriter(crw, buffer)
// Serve the request with the multiwriter
next.ServeHTTP(multi, r)
// Calculate the duration
duration := time.Since(start)
// Calculate the size
size := buffer.Len()
// Log the duration, size, and status code
log.Printf("Status code: %d, Duration: %v, Size: %d bytes\n", crw.statusCode, duration, size)
})
}
func main() {
// Your actual handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
// Wrap your handler with the logging middleware, you could also router.Use this with gorilla/mux
http.Handle("/", loggingMiddleware(handler))
// Start the server
log.Fatal(http.ListenAndServe(":8080", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment