func Logger() echo.MiddlewareFunc { return func(h echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { start := time.Now() if err := h(c); err != nil { c.Error(err) } stop := time.Now() method := c.Request().Method path := c.Request().URL.Path if path == "" { path = "/" } size := c.Response().Size() n := c.Response().Status() code := color.Green(n) switch { case n >= 500: code = color.Red(n) case n >= 400: code = color.Yellow(n) case n >= 300: code = color.Cyan(n) } log.Printf("%s %s %s %s %d", method, path, code, stop.Sub(start), size) return nil } } }
// RecoverWithConfig returns a recover middleware from config. // See `Recover()`. func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc { // Defaults if config.StackSize == 0 { config.StackSize = DefaultRecoverConfig.StackSize } return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { defer func() { if r := recover(); r != nil { var err error switch r := r.(type) { case error: err = r default: err = fmt.Errorf("%v", r) } stack := make([]byte, config.StackSize) length := runtime.Stack(stack, !config.DisableStackAll) if !config.DisablePrintStack { c.Logger().Printf("[%s] %s %s", color.Red("PANIC RECOVER"), err, stack[:length]) } c.Error(err) } }() return next(c) } } }
func initLevels() { levels = []string{ color.Blue("DEBUG"), color.Green("INFO"), color.Yellow("WARN"), color.Red("ERROR"), color.RedBg("FATAL"), } }
func initLevels() { levels = []string{ color.Cyan("TRACE"), color.Blue("DEBUG"), color.Green("INFO"), color.Magenta("NOTICE"), color.Yellow("WARN"), color.Red("ERROR"), color.RedBg("FATAL"), } }
func Logger() echo.MiddlewareFunc { return func(h echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { req := c.Request() res := c.Response() logger := c.Echo().Logger() remoteAddr := req.RemoteAddr if ip := req.Header.Get(echo.XRealIP); ip != "" { remoteAddr = ip } else if ip = req.Header.Get(echo.XForwardedFor); ip != "" { remoteAddr = ip } else { remoteAddr, _, _ = net.SplitHostPort(remoteAddr) } start := time.Now() if err := h(c); err != nil { c.Error(err) } stop := time.Now() method := req.Method path := req.URL.Path if path == "" { path = "/" } size := res.Size() n := res.Status() code := color.Green(n) switch { case n >= 500: code = color.Red(n) case n >= 400: code = color.Yellow(n) case n >= 300: code = color.Cyan(n) } logger.Info("%14v %-20s %3s %4s %s [%d]", stop.Sub(start), // Продолжительность обработки запроса remoteAddr, // IP-адрес того, кто осуществляет запрос code, // Статус ответа method, // Метод HTTP-запроса path, // Запрашиваемый URL size, // размер ответа ) return nil } } }
func Logger() echo.MiddlewareFunc { return func(h echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { req := c.Request() res := c.Response() logger := c.Echo().Logger() remoteAddr := req.RemoteAddr if ip := req.Header.Get(echo.XRealIP); ip != "" { remoteAddr = ip } else if ip = req.Header.Get(echo.XForwardedFor); ip != "" { remoteAddr = ip } else { remoteAddr, _, _ = net.SplitHostPort(remoteAddr) } start := time.Now() if err := h(c); err != nil { c.Error(err) } stop := time.Now() method := req.Method path := req.URL.Path if path == "" { path = "/" } size := res.Size() n := res.Status() code := color.Green(n) switch { case n >= 500: code = color.Red(n) case n >= 400: code = color.Yellow(n) case n >= 300: code = color.Cyan(n) } logger.Info("%s %s %s %s %s %d", remoteAddr, method, path, code, stop.Sub(start), size) return nil } } }
func (l *Logger) SetOutput(w io.Writer) { l.out = w l.err = w color.Disable() switch w := w.(type) { case *os.File: if isatty.IsTerminal(w.Fd()) { color.Enable() } levels = []string{ color.Cyan("TRACE"), color.Blue("DEBUG"), color.Green("INFO"), color.Magenta("NOTICE"), color.Yellow("WARN"), color.Red("ERROR"), color.RedBg("FATAL"), } } }
// Err prints an error message. It does not cause an exit. func Err(format string, v ...interface{}) { fmt.Fprint(Stderr, color.Red("[ERROR] ")) fmt.Fprintf(Stderr, appendNewLine(format), v...) }
// LoggerFromConfig returns a logger middleware from config. // See `Logger()`. func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc { config.template = fasttemplate.New(config.Format, "${", "}") config.color = color.New() if w, ok := config.Output.(*os.File); ok && !isatty.IsTerminal(w.Fd()) { config.color.Disable() } return func(next echo.Handler) echo.Handler { return echo.HandlerFunc(func(c echo.Context) (err error) { rq := c.Request() rs := c.Response() start := time.Now() if err = next.Handle(c); err != nil { c.Error(err) } stop := time.Now() _, err = config.template.ExecuteFunc(config.Output, func(w io.Writer, tag string) (int, error) { switch tag { case "time_rfc3339": return w.Write([]byte(time.Now().Format(time.RFC3339))) case "remote_ip": ra := rq.RemoteAddress() if ip := rq.Header().Get(echo.XRealIP); ip != "" { ra = ip } else if ip = rq.Header().Get(echo.XForwardedFor); ip != "" { ra = ip } else { ra, _, _ = net.SplitHostPort(ra) } return w.Write([]byte(ra)) case "uri": return w.Write([]byte(rq.URI())) case "method": return w.Write([]byte(rq.Method())) case "path": p := rq.URL().Path() if p == "" { p = "/" } return w.Write([]byte(p)) case "status": n := rs.Status() s := color.Green(n) switch { case n >= 500: s = color.Red(n) case n >= 400: s = color.Yellow(n) case n >= 300: s = color.Cyan(n) } return w.Write([]byte(s)) case "response_time": return w.Write([]byte(stop.Sub(start).String())) case "response_size": return w.Write([]byte(strconv.FormatInt(rs.Size(), 10))) default: return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag))) } }) return }) } }