Skip to content

Instantly share code, notes, and snippets.

@ascarter
Created December 31, 2014 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ascarter/26953500f76410ca1eef to your computer and use it in GitHub Desktop.
Save ascarter/26953500f76410ca1eef to your computer and use it in GitHub Desktop.
HTTP request logger in Go
package __package__
import (
"net/http"
"time"
)
type responseLogger struct {
w http.ResponseWriter
status int
size int
}
func (r *responseLogger) Header() http.Header {
return r.w.Header()
}
func (r *responseLogger) Write(b []byte) (int, error) {
if r.status == 0 {
// Status will be StatusOK if WriteHeader not called yet
r.status = http.StatusOK
}
size, err := r.w.Write(b)
r.size += size
return size, err
}
func (r *responseLogger) WriteHeader(s int) {
r.w.WriteHeader(s)
r.status = s
}
func (r *responseLogger) Status() int {
return r.status
}
func (r *responseLogger) Size() int {
return r.size
}
// LogRequest logs starting and ending messages for HTTP request with duration
func LogRequest(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rw := &responseLogger{w: w}
raddr := r.Header.Get("X-Forwarded-For")
if raddr == "" {
raddr = r.RemoteAddr
}
Infof("Started %s %s for %s", r.Method, r.URL.Path, raddr)
h.ServeHTTP(rw, r)
Infof("Completed %v %s in %v",
rw.Status(),
http.StatusText(rw.Status()),
time.Since(start))
})
}
// LogRequestHandler return a LogRequest handler
func LogRequestHandler(f http.HandlerFunc) http.Handler {
return LogRequest(http.HandlerFunc(f))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment