package serverconfig import ( "encoding/json" "io" "strconv" "time" "bitbucket.org/nemt/nemt-portal-api/infra/logger" "github.com/Sirupsen/logrus" "github.com/labstack/echo" "github.com/labstack/gommon/log" ) type echoLogger struct { *logger.Logger } // Printj prints a message in json format func (l *echoLogger) Printj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Print(string(bytes)) } // Debugj logs a debug message in json format func (l *echoLogger) Debugj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Debug(string(bytes)) } // Infoj logs an info message in json format func (l *echoLogger) Infoj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Info(string(bytes)) } // Warnj logs a warning message in json format func (l *echoLogger) Warnj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Warn(string(bytes)) } // Errorj logs an error message in json format func (l *echoLogger) Errorj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Error(string(bytes)) } // Panicj logs a panic message in json format func (l *echoLogger) Panicj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Panic(string(bytes)) } // Fatalj logs a fatal message in json format func (l *echoLogger) Fatalj(data log.JSON) { bytes, _ := json.Marshal(data) l.Logger.Fatal(string(bytes)) } // Level returns the echo logging level func (l *echoLogger) Level() log.Lvl { return log.Lvl(l.Logger.Level) } // SetLevel sets the echo logging level func (l *echoLogger) SetLevel(level log.Lvl) { l.Logger.Level = logrus.Level(level) } // Output returns the echo logging output func (l *echoLogger) Output() io.Writer { return l.Writer() } // SetOutput sets the echo logging output func (l *echoLogger) SetOutput(output io.Writer) { l.Logger.Logger.Out = output } // Prefix returns the echo logging output func (l *echoLogger) Prefix() string { return l.Logger.Data["app"].(string) } // SetPrefix returns the echo logging output func (l *echoLogger) SetPrefix(prefix string) { l.Logger.Data["app"] = prefix } func loggerMiddlewareHandler(c echo.Context, next echo.HandlerFunc, log *logger.Logger) error { req := c.Request() res := c.Response() start := time.Now() err := next(c) if err != nil { return err } stop := time.Now() p := req.URL.Path if p == "" { p = "/" } bytesIn := req.Header.Get(echo.HeaderContentLength) if bytesIn == "" { bytesIn = "0" } requestID := req.Header.Get(echo.HeaderXRequestID) if requestID == "" { requestID = res.Header().Get(echo.HeaderXRequestID) } log.WithFields(map[string]interface{}{ "id": requestID, "time_rfc3339": time.Now().Format(time.RFC3339), "remote_ip": c.RealIP(), "host": req.Host, "uri": req.RequestURI, "method": req.Method, "path": p, "referer": req.Referer(), "user_agent": req.UserAgent(), "status": res.Status, "latency": strconv.FormatInt(stop.Sub(start).Nanoseconds()/1000, 10), "latency_human": stop.Sub(start).String(), "bytes_in": bytesIn, "bytes_out": strconv.FormatInt(res.Size, 10), "headers": req.Header, "query": req.URL.Query(), }).Info("Handled request") return nil } func loggerMiddleware(log *logger.Logger) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { return loggerMiddlewareHandler(c, next, log) } } } func setLogMiddleware(e *echo.Echo, log *logger.Logger) { e.Logger = &echoLogger{log} e.Pre(loggerMiddleware(log)) }