package logger import ( "log" "os" "path/filepath" "sync" "time" ) // Logger 全局日志实例 var Logger *log.Logger var logFile *os.File var logFileName string var mu sync.Mutex // InitLogger 初始化日志,创建 /data/logs 目录并按天命名文件 func InitLogger() error { mu.Lock() defer mu.Unlock() // 创建 /data/logs 目录 logDir := "/data/logs" if err := os.MkdirAll(logDir, 0755); err != nil { return err } // 按天生成日志文件名:20260102.log logFileName = filepath.Join(logDir, time.Now().Format("20060102")+".log") file, err := os.OpenFile(logFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } logFile = file Logger = log.New(file, "", log.LstdFlags) // 启动日志文件切换和清理的goroutine go startLogMaintenance() return nil } // startLogMaintenance 启动日志维护(文件切换和清理) func startLogMaintenance() { // 每天凌晨检查是否需要切换日志文件 ticker := time.NewTicker(1 * time.Hour) // 每小时检查一次 defer ticker.Stop() for range ticker.C { checkLogFileSwitch() // 每天凌晨2点执行日志清理 if time.Now().Hour() == 2 { CleanupOldLogs() } } } // checkLogFileSwitch 检查并切换日志文件 func checkLogFileSwitch() { mu.Lock() defer mu.Unlock() if logFile == nil { return } newFileName := filepath.Join("/data/logs", time.Now().Format("20060102")+".log") if newFileName != logFileName { newFile, err := os.OpenFile(newFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Printf("切换日志文件失败: %v", err) return } logFile.Close() logFile = newFile logFileName = newFileName Logger = log.New(newFile, "", log.LstdFlags) Logger.Printf("日志文件已切换到: %s", newFileName) } } // CloseLogger 关闭日志文件 func CloseLogger() { mu.Lock() defer mu.Unlock() if logFile != nil { logFile.Close() logFile = nil } } // Close 是 CloseLogger 的别名,提供兼容性 func Close() { CloseLogger() } // CleanupOldLogs 删除超过30天的日志文件 func CleanupOldLogs() { logDir := "/data/logs" files, err := os.ReadDir(logDir) if err != nil { if Logger != nil { Logger.Printf("读取日志目录 %s 错误: %v", logDir, err) } return } const maxAge = 30 * 24 * time.Hour // 30天 cutoffTime := time.Now().Add(-maxAge) for _, file := range files { if file.IsDir() { continue } info, err := file.Info() if err != nil { if Logger != nil { Logger.Printf("获取文件信息 %s 错误: %v", file.Name(), err) } continue } if info.ModTime().Before(cutoffTime) { filePath := filepath.Join(logDir, file.Name()) if err := os.Remove(filePath); err != nil { if Logger != nil { Logger.Printf("删除旧日志文件 %s 错误: %v", filePath, err) } } else { if Logger != nil { Logger.Printf("删除旧日志文件 %s 成功", filePath) } } } } }