Julien's dev blog

Gist: Go HTTP logging middleware

Example of a simple HTTP logging middleware implementation in Go.

Last updated on: 2024-12-29

package httpmux

import "net/http"

type ResponseRecorderWriter struct {
	http.ResponseWriter
	StatusCode int
	Written    int
}

var _ http.ResponseWriter = (*ResponseRecorderWriter)(nil)

func (w *ResponseRecorderWriter) WriteHeader(statusCode int) {
	w.ResponseWriter.WriteHeader(statusCode)
	w.StatusCode = statusCode
}

func (w *ResponseRecorderWriter) Write(b []byte) (n int, err error) {
	n, err = w.ResponseWriter.Write(b)
	w.Written += n
	return n, err
}

type LoggingHandlerFunc func(w *ResponseRecorderWriter, r *http.Request)

// Note: Response recorder's status code is initialized to -1 to allow for
// checking if a header has already been written.
func NewLoggingMiddleware(onHandled LoggingHandlerFunc) Middleware {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			resrec := &ResponseRecorderWriter{ResponseWriter: w, StatusCode: -1}
			h.ServeHTTP(resrec, r)
			onHandled(resrec, r)
		})
	}
}
Go code