package logger import ( "fmt" "io" "os" "path/filepath" "sync" "github.com/sirupsen/logrus" ) var ( log *logrus.Logger logMutex sync.Mutex initialized bool ) // InitLogger 初始化日志系统 func InitLogger(logFile, level string, maxSize, maxBackups, maxAge int, _ bool) error { logMutex.Lock() defer logMutex.Unlock() if initialized { return nil } log = logrus.New() // 配置日志格式 log.SetFormatter(&logrus.TextFormatter{ FullTimestamp: true, }) // 创建日志目录 if logFile != "" { logDir := filepath.Dir(logFile) if logDir != "." { if err := os.MkdirAll(logDir, 0755); err != nil { return fmt.Errorf("创建日志目录失败: %w", err) } } } // 设置输出目标 outputTargets := []io.Writer{} if logFile != "" { // 使用标准库打开文件,支持追加写入 file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { // 无法打开日志文件时,回退到标准输出 log.Println("无法打开日志文件,将使用标准输出:", err) } else { outputTargets = append(outputTargets, file) defer file.Sync() // 确保日志内容被写入磁盘 } } // 无论是否指定日志文件,都同时输出到标准输出 if len(outputTargets) > 0 { outputTargets = append(outputTargets, os.Stdout) } else { // 如果没有指定日志文件,仅使用标准输出 outputTargets = append(outputTargets, os.Stdout) } // 设置日志输出 log.SetOutput(io.MultiWriter(outputTargets...)) // 设置日志级别 logLevel, err := logrus.ParseLevel(level) if err != nil { logLevel = logrus.InfoLevel } log.SetLevel(logLevel) initialized = true return nil } // Close 关闭日志系统 func Close() { logMutex.Lock() defer logMutex.Unlock() if !initialized || log == nil { return } // 执行日志刷新 log.Warn("日志系统已关闭") // 确保日志被写入磁盘 if loggerOutput, ok := log.Out.(*os.File); ok { loggerOutput.Sync() } initialized = false log = nil } // Info 记录信息级别日志 func Info(msg string, fields ...interface{}) { if !initialized { return } if len(fields) > 0 { log.WithFields(toFields(fields)).Info(msg) } else { log.Info(msg) } } // Error 记录错误级别日志 func Error(msg string, fields ...interface{}) { if !initialized { return } if len(fields) > 0 { log.WithFields(toFields(fields)).Error(msg) } else { log.Error(msg) } } // Debug 记录调试级别日志 func Debug(msg string, fields ...interface{}) { if !initialized { return } if len(fields) > 0 { log.WithFields(toFields(fields)).Debug(msg) } else { log.Debug(msg) } } // Warn 记录警告级别日志 func Warn(msg string, fields ...interface{}) { if !initialized { return } if len(fields) > 0 { log.WithFields(toFields(fields)).Warn(msg) } else { log.Warn(msg) } } // Fatal 记录致命级别日志并退出程序 func Fatal(msg string, fields ...interface{}) { if !initialized { // 如果日志系统未初始化,使用标准库log log.Fatal(msg) } if len(fields) > 0 { log.WithFields(toFields(fields)).Fatal(msg) } else { log.Fatal(msg) } } // toFields 将键值对转换为logrus字段 func toFields(keyValues []interface{}) logrus.Fields { fields := make(logrus.Fields) for i := 0; i < len(keyValues); i += 2 { if i+1 < len(keyValues) { fields[keyValues[i].(string)] = keyValues[i+1] } } return fields }