package log import ( "fmt" "os" "path/filepath" "runtime" "strconv" "strings" "time" rotatelogs "github.com/lestrrat-go/file-rotatelogs" "github.com/sirupsen/logrus" ) func init() { logrus.SetFormatter(&DFormatter{}) logrus.SetLevel(DebugLevel) logrus.SetOutput(os.Stdout) } // type PanicLevel = logrus.PanicLevel const ( PanicLevel logrus.Level = logrus.PanicLevel FatalLevel logrus.Level = logrus.FatalLevel ErrorLevel logrus.Level = logrus.ErrorLevel WarnLevel logrus.Level = logrus.WarnLevel InfoLevel logrus.Level = logrus.InfoLevel DebugLevel logrus.Level = logrus.DebugLevel ) var ( fileConn *rotatelogs.RotateLogs ) type LogConfig struct { Filename string // 日志文件 RetainFileCount uint // 保留日志文件数量 IsDevelop bool // 开发模式会输出日志到标准输出 FileSplitTime time.Duration // 日志文件拆分时间间隔 time.Hour*24 } func WithField(key string, value string) *logrus.Entry { return logrus.WithField(key, value) } // config need to be correct JSON as string: {"filename":"default.log","maxsize":100} func SetLogger(config LogConfig) *logrus.Logger { /* 日志轮转相关函数 `WithLinkName` 为最新的日志建立软连接 `WithRotationTime` 设置日志分割的时间,隔多久分割一次 WithMaxAge 和 WithRotationCount二者只能设置一个 `WithMaxAge` 设置文件清理前的最长保存时间 `WithRotationCount` 设置文件清理前最多保存的个数 */ //fileName := config.Filename + ".%Y%m%d" fileName := "" if config.FileSplitTime > time.Hour { fileName = fmt.Sprintf(config.Filename, "%Y%m%d") } else if config.FileSplitTime > time.Minute*30 { fileName = fmt.Sprintf(config.Filename, "%Y%m%d_%H") } else { fileName = fmt.Sprintf(config.Filename, "%Y%m%d_%H_%M") } fileConn, _ := rotatelogs.New( fileName, //rotatelogs.WithLinkName(config.Filename), rotatelogs.WithRotationCount(config.RetainFileCount), rotatelogs.WithRotationTime(config.FileSplitTime), ) if config.IsDevelop { fmt.Println("isDeubg=true; log out console") logrus.SetLevel(DebugLevel) logrus.SetOutput(os.Stdout) } else { fmt.Println("isDeubg=false; log out file") logrus.SetOutput(fileConn) } return logrus.StandardLogger() } func GetFileConn() *rotatelogs.RotateLogs { return fileConn } func SetLevel(logLevel logrus.Level) { logrus.SetLevel(logLevel) } type DFormatter struct { TimestampFormat string } func (f *DFormatter) Format(entry *logrus.Entry) ([]byte, error) { timestampFormat := f.TimestampFormat if timestampFormat == "" { timestampFormat = "2006/01/02 15:04:05" } _, file, line, ok := runtime.Caller(9) if !ok { file = "???" line = 0 } file = filepath.Base(file) // 只取文件路径的文件名 // _, filename := path.Split(file) msg := entry.Time.Format(timestampFormat) + " " + strings.ToUpper(entry.Level.String()) + " [" + file + ":" + strconv.Itoa(line) + "] " + entry.Message + "\n" return []byte(msg), nil } func Debugf(format string, args ...interface{}) { logrus.Debugf(format, args...) } func Infof(format string, args ...interface{}) { logrus.Infof(format, args...) } func Warnf(format string, args ...interface{}) { logrus.Warnf(format, args...) } func Errorf(format string, args ...interface{}) { logrus.Errorf(format, args...) } func Fatalf(format string, args ...interface{}) { logrus.Fatalf(format, args...) } func Panicf(format string, args ...interface{}) { logrus.Panicf(format, args...) } // 以下函数不可以写成这种形式 // func Debug(args ...interface{}) { // logrus.Debug(args...) // } func Debug(args ...interface{}) { debug(args...) } func debug(args ...interface{}) { logrus.Debug(args...) } func Println(args ...interface{}) { println(args...) } func println(args ...interface{}) { logrus.Println(args...) } func Info(args ...interface{}) { info(args...) } func info(args ...interface{}) { logrus.Info(args...) } func Warn(args ...interface{}) { warn(args...) } func warn(args ...interface{}) { logrus.Warn(args...) } func Error(args ...interface{}) { ferror(args...) } func ferror(args ...interface{}) { logrus.Error(args...) } func Fatal(args ...interface{}) { fatal(args...) } func fatal(args ...interface{}) { logrus.Fatal(args...) } func Panic(args ...interface{}) { panic(args...) } func panic(args ...interface{}) { logrus.Panic(args...) }