package logger import ( "fmt" "log" "os" "sync" ) // Level 日志级别 type Level int const ( LevelDebug Level = iota LevelInfo LevelWarn LevelError LevelFatal ) // Logger 日志接口 type Logger interface { Debug(format string, args ...interface{}) Info(format string, args ...interface{}) Warn(format string, args ...interface{}) Error(format string, args ...interface{}) Fatal(format string, args ...interface{}) SetLevel(level Level) } // stdLogger 标准库日志实现 type stdLogger struct { logger *log.Logger level Level mu sync.RWMutex } // New 创建标准库日志实例 func New(config *Config) Logger { var output *os.File switch config.Output { case "stdout": output = os.Stdout case "stderr": output = os.Stderr default: var err error output, err = os.OpenFile(config.Output, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { output = os.Stdout } } level := parseLevel(config.Level) return &stdLogger{ logger: log.New(output, "", log.LstdFlags|log.Lshortfile), level: level, } } // parseLevel 解析日志级别 func parseLevel(level string) Level { switch level { case "debug": return LevelDebug case "info": return LevelInfo case "warn": return LevelWarn case "error": return LevelError case "fatal": return LevelFatal default: return LevelInfo } } // SetLevel 设置日志级别 func (l *stdLogger) SetLevel(level Level) { l.mu.Lock() defer l.mu.Unlock() l.level = level } // Debug 输出调试日志 func (l *stdLogger) Debug(format string, args ...interface{}) { if l.shouldLog(LevelDebug) { l.log("DEBUG", format, args...) } } // Info 输出信息日志 func (l *stdLogger) Info(format string, args ...interface{}) { if l.shouldLog(LevelInfo) { l.log("INFO", format, args...) } } // Warn 输出警告日志 func (l *stdLogger) Warn(format string, args ...interface{}) { if l.shouldLog(LevelWarn) { l.log("WARN", format, args...) } } // Error 输出错误日志 func (l *stdLogger) Error(format string, args ...interface{}) { if l.shouldLog(LevelError) { l.log("ERROR", format, args...) } } // Fatal 输出致命错误日志并退出 func (l *stdLogger) Fatal(format string, args ...interface{}) { if l.shouldLog(LevelFatal) { l.log("FATAL", format, args...) os.Exit(1) } } // shouldLog 判断是否应该记录日志 func (l *stdLogger) shouldLog(level Level) bool { l.mu.RLock() defer l.mu.RUnlock() return level >= l.level } // log 记录日志 func (l *stdLogger) log(level string, format string, args ...interface{}) { message := fmt.Sprintf(format, args...) l.logger.Printf("[%s] %s", level, message) } // Config 日志配置 type Config struct { Level string Format string Output string }