From 48c2cda3bff2ef52c4fb708508d54b6016dc5380 Mon Sep 17 00:00:00 2001 From: Ken Hibino Date: Tue, 8 Dec 2020 06:46:27 -0800 Subject: [PATCH] Update logging middleware to log in apache common format --- middlewares.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/middlewares.go b/middlewares.go index 69869ad..56d078e 100644 --- a/middlewares.go +++ b/middlewares.go @@ -2,15 +2,59 @@ package main import ( "fmt" + "net" "net/http" "os" + "strconv" "time" ) +// A responseRecorderWriter records response status and size. +// It implements http.ResponseWriter interface. +type responseRecorderWriter struct { + http.ResponseWriter + // The status code that the server sends back to the client. + status int + // The size of the object returned to the client, not including the response headers. + size int +} + +func (w *responseRecorderWriter) WriteHeader(status int) { + w.ResponseWriter.WriteHeader(status) + w.status = status +} + +func (w *responseRecorderWriter) Write(b []byte) (int, error) { + // If WriteHeader is not called explicitly, the first call to Write + // will trigger an implicit WriteHeader(http.StatusOK). + if w.status == 0 { + w.status = http.StatusOK + } + n, err := w.ResponseWriter.Write(b) + w.size += n + return n, err +} + func loggingMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(os.Stdout, "%v \"%s %s\"\n", - time.Now().Format(time.RFC3339), r.Method, r.URL) - h.ServeHTTP(w, r) + rw := &responseRecorderWriter{ResponseWriter: w} + h.ServeHTTP(rw, r) + + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + host = r.RemoteAddr + } + username := "-" + if user := r.URL.User; user != nil { + username = user.Username() + } + size := "-" + if rw.size > 0 { + size = strconv.Itoa(rw.size) + } + // Write a log in Apache common log format (http://httpd.apache.org/docs/2.2/logs.html#common). + fmt.Fprintf(os.Stdout, "%s - %s [%s] \"%s %s %s\" %d %s\n", + host, username, time.Now().Format("02/Jan/2006:15:04:05 -0700"), + r.Method, r.URL, r.Proto, rw.status, size) }) }