|
@@ -0,0 +1,112 @@
|
|
|
+package logger
|
|
|
+
|
|
|
+import (
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/sirupsen/logrus"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ Disabled = iota
|
|
|
+ InfoLevel
|
|
|
+ WarningLevel
|
|
|
+ DebugLevel
|
|
|
+)
|
|
|
+
|
|
|
+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
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+var loggerLevel int = InfoLevel
|
|
|
+
|
|
|
+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)
|
|
|
+
|
|
|
+ if loggerLevel >= InfoLevel {
|
|
|
+ logrus.WithFields(logrus.Fields{
|
|
|
+ "URI": req.RequestURI,
|
|
|
+ "Method": req.Method,
|
|
|
+ "Status": responseData.status,
|
|
|
+ "Duration": duration,
|
|
|
+ "Size": responseData.size,
|
|
|
+ }).Info("Completed.")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return http.HandlerFunc(loggingFn)
|
|
|
+}
|
|
|
+
|
|
|
+func SetLevel(level int) {
|
|
|
+ loggerLevel = level
|
|
|
+}
|
|
|
+
|
|
|
+func Info(v ...interface{}) {
|
|
|
+ if loggerLevel >= InfoLevel {
|
|
|
+ log.Println(v...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Infof(format string, v ...interface{}) {
|
|
|
+ if loggerLevel >= InfoLevel {
|
|
|
+ log.Printf(format, v...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Warning(v ...interface{}) {
|
|
|
+ if loggerLevel >= WarningLevel {
|
|
|
+ log.Println(v...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Warningf(format string, v ...interface{}) {
|
|
|
+ if loggerLevel >= WarningLevel {
|
|
|
+ log.Printf(format, v...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Debug(v ...interface{}) {
|
|
|
+ if loggerLevel >= DebugLevel {
|
|
|
+ log.Println(v...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Debugf(format string, v ...interface{}) {
|
|
|
+ if loggerLevel >= DebugLevel {
|
|
|
+ log.Printf(format, v...)
|
|
|
+ }
|
|
|
+}
|