package log // import ( // "fmt" // "sync" // "time" // rotatelogs "github.com/lestrrat-go/file-rotatelogs" // lfshook "github.com/rifflock/lfshook" // "github.com/sirupsen/logrus" // ) // type DoubleFileLogger struct { // infoLogger *logrus.Logger // errorLogger *logrus.Logger // channel chan *logrus.Entry // wg sync.WaitGroup // } // func NewDoubleFileLogger(fileName string, logLevel logrus.Level) (Logger, error) { // initLog := func(fileName2 string, logLevel logrus.Level, rotationTime time.Duration) (*logrus.Logger, error) { // // 初始化rotatelogs // writer, err := rotatelogs.New( // fileName2+".%Y%m%d%H.log", // rotatelogs.WithLinkName(fileName2), // // WithMaxAge和WithRotationCount只能选其一 // rotatelogs.WithRotationCount(7), // rotatelogs.WithRotationTime(rotationTime), // ) // if err != nil { // return nil, err // } // // 设置lfshook // writeMap := lfshook.WriterMap{ // logrus.DebugLevel: writer, // logrus.InfoLevel: writer, // logrus.WarnLevel: writer, // logrus.ErrorLevel: writer, // logrus.FatalLevel: writer, // logrus.PanicLevel: writer, // } // hook := lfshook.NewHook(writeMap, &logrus.TextFormatter{ // TimestampFormat: "2006-01-02 15:04:05", // }) // // 初始化logrus并添加hook // logger := logrus.New() // logger.SetLevel(logrus.Level(logLevel)) // logger.Hooks.Add(hook) // // 屏蔽logrus的日志输出,只使用HOOKS // logger.SetFormatter(&NilFormatter{}) // logger.SetOutput(&NilWriter{}) // return logger, nil // } // log1, err1 := initLog(fileName, logLevel, time.Hour*24) // log2, err2 := initLog(fileName+".error", ErrorLevel, time.Hour*24*10) // if err1 != nil { // return nil, err1 // } // if err2 != nil { // return nil, err2 // } // channel := make(chan *logrus.Entry, 100) // 有缓冲的通道,防止阻塞 // log3 := &DoubleFileLogger{ // infoLogger: log1, // errorLogger: log2, // channel: channel, // } // log3.wg.Add(1) // go log3.startWorker() // return log3, nil // } // func (dfl *DoubleFileLogger) startWorker() { // defer dfl.wg.Done() // for entry := range dfl.channel { // entry.Log(entry.Level, entry.Message) // } // // dfl.infoLogger.Info("log worker exit") // } // func (dfl *DoubleFileLogger) Close() { // close(dfl.channel) // dfl.wg.Wait() // } // func (dfl *DoubleFileLogger) Log(level Level, msg string) { // if dfl.infoLogger.IsLevelEnabled(logrus.Level(level)) { // entry := logrus.NewEntry(dfl.infoLogger) // entry.Level = logrus.Level(level) // entry.Message = msg // dfl.channel <- entry // } // if dfl.errorLogger.IsLevelEnabled(logrus.Level(level)) { // dfl.errorLogger.Log(logrus.Level(level), msg) // } // } // func (dfl *DoubleFileLogger) Logf(level Level, format string, args ...interface{}) { // if dfl.infoLogger.IsLevelEnabled(logrus.Level(level)) { // entry := logrus.NewEntry(dfl.infoLogger) // entry.Level = logrus.Level(level) // entry.Message = fmt.Sprintf(format, args...) // dfl.channel <- entry // } // if dfl.errorLogger.IsLevelEnabled(logrus.Level(level)) { // dfl.errorLogger.Logf(logrus.Level(level), format, args...) // } // } // func sprintlnn(args ...interface{}) string { // msg := fmt.Sprintln(args...) // return msg[:len(msg)-1] // } // func (dfl *DoubleFileLogger) Logln(level Level, args ...interface{}) { // if dfl.infoLogger.IsLevelEnabled(logrus.Level(level)) { // entry := logrus.NewEntry(dfl.infoLogger) // entry.Level = logrus.Level(level) // entry.Message = sprintlnn(args...) // dfl.channel <- entry // } // if dfl.errorLogger.IsLevelEnabled(logrus.Level(level)) { // dfl.errorLogger.Logln(logrus.Level(level), args...) // } // } // func (dfl *DoubleFileLogger) Info(msg string) { // dfl.Log(InfoLevel, msg) // } // func (dfl *DoubleFileLogger) Infof(format string, args ...interface{}) { // dfl.Logf(InfoLevel, format, args...) // } // func (dfl *DoubleFileLogger) Infoln(args ...interface{}) { // dfl.Logln(InfoLevel, args...) // } // func (dfl *DoubleFileLogger) Warn(msg string) { // dfl.Log(WarnLevel, msg) // } // func (dfl *DoubleFileLogger) Warnf(format string, args ...interface{}) { // dfl.Logf(WarnLevel, format, args...) // } // func (dfl *DoubleFileLogger) Warnln(args ...interface{}) { // dfl.Logln(WarnLevel, args...) // } // func (dfl *DoubleFileLogger) Error(msg string) { // dfl.Log(ErrorLevel, msg) // } // func (dfl *DoubleFileLogger) Errorf(format string, args ...interface{}) { // dfl.Logf(ErrorLevel, format, args...) // } // func (dfl *DoubleFileLogger) Errorln(args ...interface{}) { // dfl.Logln(ErrorLevel, args...) // } // func (dfl *DoubleFileLogger) Debug(msg string) { // dfl.Log(DebugLevel, msg) // } // func (dfl *DoubleFileLogger) Debugf(format string, args ...interface{}) { // dfl.Logf(DebugLevel, format, args...) // } // func (dfl *DoubleFileLogger) Debugln(args ...interface{}) { // dfl.Logln(DebugLevel, args...) // } // func (dfl *DoubleFileLogger) Fatal(msg string) { // dfl.Log(FatalLevel, msg) // } // func (dfl *DoubleFileLogger) Fatalf(format string, args ...interface{}) { // dfl.Logf(FatalLevel, format, args...) // } // func (dfl *DoubleFileLogger) Fatalln(args ...interface{}) { // dfl.Logln(FatalLevel, args...) // } // func (dfl *DoubleFileLogger) Panic(msg string) { // dfl.Log(PanicLevel, msg) // } // func (dfl *DoubleFileLogger) Panicf(format string, args ...interface{}) { // dfl.Logf(PanicLevel, format, args...) // } // func (dfl *DoubleFileLogger) Panicln(args ...interface{}) { // dfl.Logln(PanicLevel, args...) // } // type NilFormatter struct { // } // func (nf *NilFormatter) Format(*logrus.Entry) ([]byte, error) { // return nil, nil // } // type NilWriter struct { // } // func (nf *NilWriter) Write(p []byte) (n int, err error) { // return 0, nil // } // func testDoubleFileLogger() { // logger, err := NewDoubleFileLogger("./logs/test.log", InfoLevel) // if err != nil { // panic(err) // } // // 记录日志 // logger.Debug("这是一条调试日志,使用lfshook") // logger.Info("这是一条信息日志,使用lfshook") // // ... 其他日志 // }