// Package logging - 日志系统 // // 技术债务警告: // 这个包过于复杂(577行代码实现5个日志函数),违反了Linus的"简洁优雅"原则。 // 当前保留是因为功能正常且重构风险较高,但未来应考虑简化。 // 理想实现:用标准库+简单封装替代当前的抽象层架构。 package logging import ( "fmt" "io" "log" "path/filepath" "runtime" "sync" "time" "github.com/fatih/color" ) // Logger 日志管理器 type Logger struct { mu sync.RWMutex config *LoggerConfig formatter LogFormatter handlers []LogHandler scanStatus *ScanStatus progressBar ProgressDisplay outputMutex *sync.Mutex initialized bool } // NewLogger 创建新的日志管理器 func NewLogger(config *LoggerConfig) *Logger { if config == nil { config = DefaultLoggerConfig() } logger := &Logger{ config: config, formatter: NewStandardFormatter(), handlers: make([]LogHandler, 0), scanStatus: NewScanStatus(), outputMutex: &sync.Mutex{}, initialized: true, } // 设置格式化器的开始时间 logger.formatter.SetStartTime(config.StartTime) // 添加默认的控制台处理器 consoleHandler := NewConsoleHandler(config) logger.AddHandler(consoleHandler) return logger } // ============================================================================================= // 已删除的死代码(未使用):SetFormatter 方法 // ============================================================================================= // AddHandler 添加日志处理器 func (l *Logger) AddHandler(handler LogHandler) { l.mu.Lock() defer l.mu.Unlock() l.handlers = append(l.handlers, handler) } // SetProgressBar 设置进度条显示 func (l *Logger) SetProgressBar(progressBar ProgressDisplay) { l.mu.Lock() defer l.mu.Unlock() l.progressBar = progressBar } // SetOutputMutex 设置输出互斥锁 func (l *Logger) SetOutputMutex(mutex *sync.Mutex) { l.mu.Lock() defer l.mu.Unlock() l.outputMutex = mutex } // SetCoordinatedOutput 设置协调输出函数(用于进度条协调) func (l *Logger) SetCoordinatedOutput(fn func(string)) { l.mu.RLock() defer l.mu.RUnlock() for _, handler := range l.handlers { if consoleHandler, ok := handler.(*ConsoleHandler); ok { consoleHandler.SetCoordinatedOutput(fn) } } } // Log 记录日志(优化版) func (l *Logger) Log(level LogLevel, content string, metadata ...map[string]interface{}) { // 早期返回,避免不必要的计算 if !l.shouldLog(level) { return } // 优化:只有在错误级别时才获取调用者信息,减少开销 if level == LevelError { if _, file, line, ok := runtime.Caller(2); ok { // 直接在content中包含位置信息,避免额外的Source字段 content = fmt.Sprintf("%s:%d - %s", filepath.Base(file), line, content) } } // 简化entry创建,减少字段赋值 entry := &LogEntry{ Level: level, Time: time.Now(), Content: content, } // 只在需要时添加元数据 if len(metadata) > 0 && metadata[0] != nil { entry.Metadata = metadata[0] } l.handleLogEntry(entry) // 更新扫描状态 if level == LevelSuccess { l.scanStatus.UpdateSuccess() } else if level == LevelError { l.scanStatus.UpdateError() } } // levelAllowMap 预计算的级别允许映射,避免运行时重复计算 var levelAllowMap = map[LogLevel]map[LogLevel]bool{ LevelAll: {LevelError: true, LevelBase: true, LevelInfo: true, LevelSuccess: true, LevelDebug: true}, LevelBaseInfoSuccess: {LevelBase: true, LevelInfo: true, LevelSuccess: true}, LevelInfoSuccess: {LevelInfo: true, LevelSuccess: true}, LevelError: {LevelError: true}, LevelBase: {LevelBase: true}, LevelInfo: {LevelInfo: true}, LevelSuccess: {LevelSuccess: true}, LevelDebug: {LevelDebug: true}, } // shouldLog 检查是否应该记录该级别的日志(优化版) func (l *Logger) shouldLog(level LogLevel) bool { // 快速查表,O(1)复杂度 if allowedLevels, exists := levelAllowMap[l.config.Level]; exists { return allowedLevels[level] } // 向后兼容:字符串"debug"显示所有 if l.config.Level == "debug" { return true } // 默认策略:显示base、info和success return level == LevelBase || level == LevelInfo || level == LevelSuccess } // handleLogEntry 处理日志条目 func (l *Logger) handleLogEntry(entry *LogEntry) { l.outputMutex.Lock() defer l.outputMutex.Unlock() // 清除进度条 l.clearProgress() // 使用所有处理器处理日志 l.mu.RLock() for _, handler := range l.handlers { if handler.IsEnabled() { handler.Handle(entry) } } l.mu.RUnlock() // 恢复进度条 l.restoreProgress() } // clearProgress 清除进度条 func (l *Logger) clearProgress() { if l.progressBar != nil { l.progressBar.Clear() // 忽略错误 time.Sleep(ProgressClearDelay) } } // restoreProgress 恢复进度条 func (l *Logger) restoreProgress() { if l.progressBar != nil { l.progressBar.RenderBlank() // 忽略错误 } } // 便利方法 func (l *Logger) Debug(content string, metadata ...map[string]interface{}) { l.Log(LevelDebug, content, metadata...) } func (l *Logger) Base(content string, metadata ...map[string]interface{}) { l.Log(LevelBase, content, metadata...) } func (l *Logger) Info(content string, metadata ...map[string]interface{}) { l.Log(LevelInfo, content, metadata...) } func (l *Logger) Success(content string, metadata ...map[string]interface{}) { l.Log(LevelSuccess, content, metadata...) } func (l *Logger) Error(content string, metadata ...map[string]interface{}) { l.Log(LevelError, content, metadata...) } // ============================================================================================= // 已删除的死代码(未使用):GetScanStatus 获取扫描状态管理器 // ============================================================================================= // Initialize 初始化日志系统(兼容原接口) func (l *Logger) Initialize() { // 禁用标准日志输出 log.SetOutput(io.Discard) } // ConsoleHandler 控制台日志处理器 type ConsoleHandler struct { config *LoggerConfig formatter LogFormatter enabled bool coordinatedOutput func(string) // 协调输出函数 mu sync.RWMutex } // NewConsoleHandler 创建控制台处理器 func NewConsoleHandler(config *LoggerConfig) *ConsoleHandler { formatter := NewStandardFormatter() formatter.SetStartTime(config.StartTime) return &ConsoleHandler{ config: config, formatter: formatter, enabled: true, } } // Handle 处理日志条目 func (h *ConsoleHandler) Handle(entry *LogEntry) { h.mu.RLock() defer h.mu.RUnlock() if !h.enabled { return } // 使用自己的格式化器格式化消息 logMsg := h.formatter.Format(entry) // 使用协调输出函数,如果设置了的话 if h.coordinatedOutput != nil { if h.config.EnableColor { if colorAttr, ok := h.config.LevelColors[entry.Level]; ok { if attr, ok := colorAttr.(color.Attribute); ok { coloredMsg := color.New(attr).Sprint(logMsg) h.coordinatedOutput(coloredMsg) } else { h.coordinatedOutput(logMsg) } } else { h.coordinatedOutput(logMsg) } } else { h.coordinatedOutput(logMsg) } } else { // 回到原来的直接输出方式 if h.config.EnableColor { if colorAttr, ok := h.config.LevelColors[entry.Level]; ok { if attr, ok := colorAttr.(color.Attribute); ok { color.New(attr).Println(logMsg) } else { fmt.Println(logMsg) } } else { fmt.Println(logMsg) } } else { fmt.Println(logMsg) } } // 根据慢速输出设置决定是否添加延迟 if h.config.SlowOutput { time.Sleep(SlowOutputDelay) } } // SetEnabled 设置处理器启用状态 func (h *ConsoleHandler) SetEnabled(enabled bool) { h.mu.Lock() defer h.mu.Unlock() h.enabled = enabled } // SetCoordinatedOutput 设置协调输出函数 func (h *ConsoleHandler) SetCoordinatedOutput(fn func(string)) { h.mu.Lock() defer h.mu.Unlock() h.coordinatedOutput = fn } // IsEnabled 检查处理器是否启用 func (h *ConsoleHandler) IsEnabled() bool { h.mu.RLock() defer h.mu.RUnlock() return h.enabled } // ============================================================================================= // 已删除的死代码(未使用):CheckErrs 错误检查函数 // =============================================================================================