package app import ( "fmt" "log" "os" "path" "strings" "sync" "time" ) const ( LogWhenSecond = iota LogWhenMinute LogWhenHour LogWhenDay ) var ( lg func(level string, data any) fd *os.File ) func ConfigLogger(file string, when int8) { // 解决 Windows 电脑路径问题 file = strings.ReplaceAll(file, "\\", "/") if err := os.MkdirAll(path.Dir(file), 0777); err != nil { panic(err) } var interval int64 var suffix string switch when { case LogWhenSecond: interval = 1 suffix = "2006-01-02_15-04-05" case LogWhenMinute: interval = 60 suffix = "2006-01-02_15-04" case LogWhenHour: interval = 3600 suffix = "2006-01-02_15" case LogWhenDay: interval = 3600 * 24 suffix = "2006-01-02" default: panic(fmt.Errorf("invalid when rotate: %d", when)) } var err error fd, err = os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { panic(err) } fInfo, err := fd.Stat() if err != nil { panic(err) } rolloverAt := fInfo.ModTime().Unix() + interval locker := sync.RWMutex{} resolveRotatedFile := func(suffix string) string { filenameWithSuffix := path.Base(file) fileSuffix := path.Ext(filenameWithSuffix) filename := strings.TrimSuffix(filenameWithSuffix, fileSuffix) return path.Dir(file) + "/" + filename + "." + suffix + fileSuffix } lg = func(level string, data any) { now := time.Now() if rolloverAt <= now.Unix() { locker.Lock() defer locker.Unlock() fName := resolveRotatedFile(now.Format(suffix)) //fName := file + now.Format(suffix) _ = fd.Close() e := os.Rename(file, fName) if e != nil { log.Println(e) return } fd, err = os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Println(e) return } now = time.Now() rolloverAt = now.Unix() + interval } t := now.Format("2006-01-02 15:04:05") _, err := fmt.Fprintf(fd, "%s [%s] %v", t, level, data) if err != nil { log.Println(err) } } } func LogError(data any) { lg("ERROR", data) } func LogWarning(data any) { lg("WARNING", data) } func LogInfo(data any) { lg("INFO", data) } func LogoDebug(data any) { lg("DEBUG", data) } func LogFatal(data any) { lg("FATAL", data) }