package log import ( "fmt" "io" "os" "path" "path/filepath" "strconv" "strings" "time" "next-terminal/server/config" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" ) type Formatter struct{} func (s *Formatter) Format(entry *logrus.Entry) ([]byte, error) { timestamp := time.Now().Local().Format("2006-01-02 15:04:05") var file string var l int if entry.HasCaller() { file = filepath.Base(entry.Caller.Function) l = entry.Caller.Line } msg := fmt.Sprintf("%s %s [%s:%d]%s\n", timestamp, strings.ToUpper(entry.Level.String()), file, l, entry.Message) return []byte(msg), nil } var stdOut = NewLogger() // Trace logs a message at level Trace on the standard logger. func Trace(args ...interface{}) { stdOut.Trace(args...) } // Debug logs a message at level Debug on the standard logger. func Debug(args ...interface{}) { stdOut.Debug(args...) } // Print logs a message at level Info on the standard logger. func Print(args ...interface{}) { stdOut.Print(args...) } // Info logs a message at level Info on the standard logger. func Info(args ...interface{}) { stdOut.Info(args...) } // Warn logs a message at level Warn on the standard logger. func Warn(args ...interface{}) { stdOut.Warn(args...) } // Warning logs a message at level Warn on the standard logger. func Warning(args ...interface{}) { stdOut.Warning(args...) } // Error logs a message at level Error on the standard logger. func Error(args ...interface{}) { stdOut.Error(args...) } // Panic logs a message at level Panic on the standard logger. func Panic(args ...interface{}) { stdOut.Panic(args...) } // Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatal(args ...interface{}) { stdOut.Fatal(args...) } // Tracef logs a message at level Trace on the standard logger. func Tracef(format string, args ...interface{}) { stdOut.Tracef(format, args...) } // Debugf logs a message at level Debug on the standard logger. func Debugf(format string, args ...interface{}) { stdOut.Debugf(format, args...) } // Printf logs a message at level Info on the standard logger. func Printf(format string, args ...interface{}) { stdOut.Printf(format, args...) } // Infof logs a message at level Info on the standard logger. func Infof(format string, args ...interface{}) { stdOut.Infof(format, args...) } // Warnf logs a message at level Warn on the standard logger. func Warnf(format string, args ...interface{}) { stdOut.Warnf(format, args...) } // Warningf logs a message at level Warn on the standard logger. func Warningf(format string, args ...interface{}) { stdOut.Warningf(format, args...) } // Errorf logs a message at level Error on the standard logger. func Errorf(format string, args ...interface{}) { stdOut.Errorf(format, args...) } // Panicf logs a message at level Panic on the standard logger. func Panicf(format string, args ...interface{}) { stdOut.Panicf(format, args...) } // Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatalf(format string, args ...interface{}) { stdOut.Fatalf(format, args...) } // Traceln logs a message at level Trace on the standard logger. func Traceln(args ...interface{}) { stdOut.Traceln(args...) } // Debugln logs a message at level Debug on the standard logger. func Debugln(args ...interface{}) { stdOut.Debugln(args...) } // Println logs a message at level Info on the standard logger. func Println(args ...interface{}) { stdOut.Println(args...) } // Infoln logs a message at level Info on the standard logger. func Infoln(args ...interface{}) { stdOut.Infoln(args...) } // Warnln logs a message at level Warn on the standard logger. func Warnln(args ...interface{}) { stdOut.Warnln(args...) } // Warningln logs a message at level Warn on the standard logger. func Warningln(args ...interface{}) { stdOut.Warningln(args...) } // Errorln logs a message at level Error on the standard logger. func Errorln(args ...interface{}) { stdOut.Errorln(args...) } // Panicln logs a message at level Panic on the standard logger. func Panicln(args ...interface{}) { stdOut.Panicln(args...) } // Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatalln(args ...interface{}) { stdOut.Fatalln(args...) } // WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. func WithError(err error) *logrus.Entry { return stdOut.WithField(logrus.ErrorKey, err) } // WithField creates an entry from the standard logger and adds a field to // it. If you want multiple fields, use `WithFields`. // // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal // or Panic on the Entry it returns. func WithField(key string, value interface{}) *logrus.Entry { return stdOut.WithField(key, value) } // Logrus : implement log type Logrus struct { *logrus.Logger } // GetEchoLogger for e.l func NewLogger() Logrus { logFilePath := "" if dir, err := os.Getwd(); err == nil { logFilePath = dir + "/logs/" } if err := os.MkdirAll(logFilePath, 0755); err != nil { fmt.Println(err.Error()) } logFileName := "next-terminal.log" //日志文件 fileName := path.Join(logFilePath, logFileName) if _, err := os.Stat(fileName); err != nil { if _, err := os.Create(fileName); err != nil { fmt.Println(err.Error()) } } //实例化 logger := logrus.New() //设置输出 logger.SetOutput(io.MultiWriter(&lumberjack.Logger{ Filename: fileName, MaxSize: 100, // megabytes MaxBackups: 3, MaxAge: 7, //days Compress: true, // disabled by default }, os.Stdout)) logger.SetReportCaller(true) //设置日志级别 if config.GlobalCfg.Debug { logger.SetLevel(logrus.DebugLevel) } else { logger.SetLevel(logrus.InfoLevel) } //设置日志格式 logger.SetFormatter(new(Formatter)) return Logrus{Logger: logger} } func logrusMiddlewareHandler(c echo.Context, next echo.HandlerFunc) error { l := NewLogger() req := c.Request() res := c.Response() start := time.Now() if err := next(c); err != nil { c.Error(err) } stop := time.Now() l.Debugf("%s %s %s %s %s %3d %s %13v %s %s", c.RealIP(), req.Host, req.Method, req.RequestURI, req.URL.Path, res.Status, strconv.FormatInt(res.Size, 10), stop.Sub(start).String(), req.Referer(), req.UserAgent(), ) return nil } func logger(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { return logrusMiddlewareHandler(c, next) } } // Hook is a function to process log. func Hook() echo.MiddlewareFunc { return logger }