fscan/common/logging/logger.go
ZacharyZcR 85a9c5e163 cleanup: 移除多余的警告标记注释,保持代码简洁
清理内容:
- 删除logging包的技术债务警告注释
- 删除parsers包的过度工程警告注释
- 移除constants.go中的TODO重构建议注释

代码整洁原则:
- 代码应该自己说话,而不是通过注释抱怨
- 警告标记在实际项目中没有价值,只会显得不专业
- 好的代码不需要为自己的复杂性道歉

验证:编译通过,功能正常
2025-09-02 01:10:37 +00:00

317 lines
8.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 错误检查函数
// =============================================================================================