Created
August 11, 2020 14:38
-
-
Save arunvelsriram/74fa35d1c9e6bbf94b8f21b42a5f07e1 to your computer and use it in GitHub Desktop.
Simple logging middleware using logrus for HTTP server provided by GoLang's net/http
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net/http" | |
"time" | |
"github.com/sirupsen/logrus" | |
) | |
func main() { | |
http.Handle("/ping", WithLogging(pingHandler())) | |
addr := "127.0.0.1:8080" | |
logrus.WithField("addr", addr).Info("starting server") | |
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil { | |
logrus.WithField("event", "start server").Fatal(err) | |
} | |
} | |
func pingHandler() http.Handler { | |
fn := func(rw http.ResponseWriter, r *http.Request) { | |
rw.WriteHeader(http.StatusOK) | |
_, _ = fmt.Fprintf(rw, "pong") | |
} | |
return http.HandlerFunc(fn) | |
} | |
type ( | |
// struct for holding response details | |
responseData struct { | |
status int | |
size int | |
} | |
// our http.ResponseWriter implementation | |
loggingResponseWriter struct { | |
http.ResponseWriter // compose original http.ResponseWriter | |
responseData *responseData | |
} | |
) | |
func (r *loggingResponseWriter) Write(b []byte) (int, error) { | |
size, err := r.ResponseWriter.Write(b) // write response using original http.ResponseWriter | |
r.responseData.size += size // capture size | |
return size, err | |
} | |
func (r *loggingResponseWriter) WriteHeader(statusCode int) { | |
r.ResponseWriter.WriteHeader(statusCode) // write status code using original http.ResponseWriter | |
r.responseData.status = statusCode // capture status code | |
} | |
func WithLogging(h http.Handler) http.Handler { | |
loggingFn := func(rw http.ResponseWriter, req *http.Request) { | |
start := time.Now() | |
responseData := &responseData{ | |
status: 0, | |
size: 0, | |
} | |
lrw := loggingResponseWriter{ | |
ResponseWriter: rw, // compose original http.ResponseWriter | |
responseData: responseData, | |
} | |
h.ServeHTTP(&lrw, req) // inject our implementation of http.ResponseWriter | |
duration := time.Since(start) | |
logrus.WithFields(logrus.Fields{ | |
"uri": req.RequestURI, | |
"method": req.Method, | |
"status": responseData.status, | |
"duration": duration, | |
"size": responseData.size, | |
}).Info("request completed") | |
} | |
return http.HandlerFunc(loggingFn) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment