diff --git a/log/index.go b/log/index.go deleted file mode 100644 index 7330d54..0000000 --- a/log/index.go +++ /dev/null @@ -1 +0,0 @@ -package log diff --git a/log/log.go b/log/log.go index d868db0..31e1104 100644 --- a/log/log.go +++ b/log/log.go @@ -5,6 +5,7 @@ import ( "io" "log" "os" + "path/filepath" "regexp" "runtime/debug" "strings" @@ -16,8 +17,11 @@ import ( ) var ( - logPath string - sysLog *log.Logger + logPath string + sysLog *log.Logger + filePath string + currentDate string // 当前日志文件对应的日期 + fileLogger *lumberjack.Logger ) const ( @@ -59,10 +63,103 @@ func (w *logWriter) Write(p []byte) (n int, err error) { return len(p), nil } -func init() { +// cleanOldLogs 删除指定天数之前的日志文件(包括主文件和备份文件) +func cleanOldLogs(days int) { + if !gfile.Exists(logPath) { + return + } + + // 获取所有日志文件 + files, err := gfile.DirNames(logPath) + if err != nil { + return + } + + now := time.Now() + for _, file := range files { + path := filepath.Join(logPath, file) + if gfile.IsDir(path) { + continue + } + + var dateStr string + var matched bool + + // 匹配主日志文件格式:log-YYYY-MM-DD.log + if strings.HasPrefix(file, "log-") && strings.HasSuffix(file, ".log") { + // 检查是否是主文件(没有备份时间戳) + // 主文件格式:log-2026-04-25.log + // 备份文件格式:log-2026-04-25-2026-04-25T10-30-45.123.log + parts := strings.Split(strings.TrimSuffix(file, ".log"), "-") + if len(parts) == 4 { + // 主文件:log-YYYY-MM-DD + dateStr = parts[1] + "-" + parts[2] + "-" + parts[3] + matched = true + } else if len(parts) > 4 { + // 备份文件:log-YYYY-MM-DD-YYYY-MM-DDTHH-MM-SS.mmm + // 提取主日期部分(第一个日期) + dateStr = parts[1] + "-" + parts[2] + "-" + parts[3] + matched = true + } + } + + if !matched { + continue + } + + // 解析日期 + fileTime, err := time.Parse("2006-01-02", dateStr) + if err != nil { + continue // 日期格式不正确,跳过 + } + + // 计算文件年龄 + tage := now.Sub(fileTime) + if tage.Hours() > float64(days*24) { + // 超过指定天数,删除文件 + err = os.Remove(path) + if err == nil { + Info(fmt.Sprintf("已删除过期日志文件:%s", file)) + } + } + } +} + +// checkAndRotateLogFile 检查是否需要切换日志文件(跨天时) +func checkAndRotateLogFile() { + date := gtime.Date() + if currentDate != date { + // 日期变化,需要重新初始化 + currentDate = date + filePath = gfile.Join(logPath, fmt.Sprintf("log-%s.log", currentDate)) + fileLogger = &lumberjack.Logger{ + Filename: filePath, + MaxSize: 2, // 单个文件最大 10MB + MaxBackups: 5, // 最多保留 5 个备份 + MaxAge: 30, // 保留 30 天 + Compress: false, // 启用压缩 + } + // 创建新的 writer + multiWriter := &logWriter{ + console: os.Stdout, + file: fileLogger, + } + sysLog = log.New(multiWriter, "", 0) + + // 清理 30 天前的旧日志 + cleanOldLogs(30) + } +} + +func Init() { + if sysLog != nil { + checkAndRotateLogFile() // 检查是否需要切换文件 + return + } logPath = gfile.Join(gfile.Pwd(), "logs") - filePath := gfile.Join(logPath, fmt.Sprintf("log-%s.log", gtime.Date())) - fileLogger := &lumberjack.Logger{ + currentDate = gtime.Date() + filePath = gfile.Join(logPath, fmt.Sprintf("log-%s.log", currentDate)) + fileLogger = &lumberjack.Logger{ Filename: filePath, MaxSize: 2, // 单个文件最大 10MB MaxBackups: 5, // 最多保留 5 个备份 @@ -75,22 +172,29 @@ func init() { file: fileLogger, } sysLog = log.New(multiWriter, "", 0) + + // 启动时清理 30 天前的旧日志 + cleanOldLogs(30) } func Info(v ...any) { + Init() sysLog.SetPrefix(fmt.Sprintf("[%s] %s[INFO]%s ", time.Now().Format("2006-01-02 15:04:05"), Green, Reset)) sysLog.Println(fmt.Sprint(v...)) } func Error(v ...any) { + Init() sysLog.SetPrefix(fmt.Sprintf("[%s] %s[ERROR]%s ", time.Now().Format("2006-01-02 15:04:05"), Red, Reset)) msg := fmt.Sprint(v...) sysLog.Println(msg, strings.TrimSpace(string(debug.Stack()))) } func Warn(v ...any) { + Init() sysLog.SetPrefix(fmt.Sprintf("[%s] %s[WARN]%s ", time.Now().Format("2006-01-02 15:04:05"), Yellow, Reset)) sysLog.Println(fmt.Sprint(v...)) } func Debug(v ...any) { + Init() sysLog.SetPrefix(fmt.Sprintf("[%s] %s[DEBUG]%s ", time.Now().Format("2006-01-02 15:04:05"), Blue, Reset)) sysLog.Println(fmt.Sprint(v...)) }