package logger import ( "fmt" "io" "os" "sync" ) // FileHook 文件钩子 - 将日志写入文件 type FileHook struct { mu sync.Mutex file *os.File output io.Writer levels []Level formatter func(*Entry) string } // NewFileHook 创建文件钩子 func NewFileHook(filename string, levels []Level) (*FileHook, error) { file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { return nil, err } return &FileHook{ file: file, output: file, levels: levels, formatter: func(e *Entry) string { return e.format() }, }, nil } // Fire 触发钩子 func (h *FileHook) Fire(entry *Entry) error { h.mu.Lock() defer h.mu.Unlock() _, err := h.output.Write([]byte(h.formatter(entry))) return err } // Levels 返回支持的日志级别 func (h *FileHook) Levels() []Level { return h.levels } // Close 关闭文件钩子 func (h *FileHook) Close() error { h.mu.Lock() defer h.mu.Unlock() return h.file.Close() } // ErrorHook 错误钩子 - 专门记录错误日志 type ErrorHook struct { mu sync.Mutex output io.Writer errors []string maxSize int } // NewErrorHook 创建错误钩子 func NewErrorHook(output io.Writer, maxSize int) *ErrorHook { return &ErrorHook{ output: output, errors: make([]string, 0, maxSize), maxSize: maxSize, } } // Fire 触发钩子 func (h *ErrorHook) Fire(entry *Entry) error { h.mu.Lock() defer h.mu.Unlock() msg := fmt.Sprintf("[%s] %s", entry.Time.Format("2006-01-02 15:04:05"), entry.Message) // 添加到缓冲区 if len(h.errors) >= h.maxSize { h.errors = h.errors[1:] } h.errors = append(h.errors, msg) // 写入输出 _, err := h.output.Write([]byte(msg + "\n")) return err } // Levels 返回支持的日志级别 func (h *ErrorHook) Levels() []Level { return []Level{ERROR, FATAL} } // GetErrors 获取最近的错误 func (h *ErrorHook) GetErrors() []string { h.mu.Lock() defer h.mu.Unlock() return h.errors } // PerformanceHook 性能钩子 - 记录慢操作 type PerformanceHook struct { mu sync.Mutex slowOps []map[string]interface{} thresholdMs float64 } // NewPerformanceHook 创建性能钩子 func NewPerformanceHook(thresholdMs float64) *PerformanceHook { return &PerformanceHook{ slowOps: make([]map[string]interface{}, 0, 100), thresholdMs: thresholdMs, } } // Fire 触发钩子 func (h *PerformanceHook) Fire(entry *Entry) error { // 只记录包含 duration 字段的日志 if duration, ok := entry.Fields["duration_ms"]; ok { var d float64 switch v := duration.(type) { case float64: d = v case int: d = float64(v) case int64: d = float64(v) default: return nil } if d > h.thresholdMs { h.mu.Lock() slowOp := map[string]interface{}{ "time": entry.Time, "operation": entry.Fields["operation"], "duration": duration, "message": entry.Message, } if len(h.slowOps) >= 100 { h.slowOps = h.slowOps[1:] } h.slowOps = append(h.slowOps, slowOp) h.mu.Unlock() } } return nil } // Levels 返回支持的日志级别 func (h *PerformanceHook) Levels() []Level { return []Level{INFO, WARN, ERROR} } // GetSlowOps 获取慢操作列表 func (h *PerformanceHook) GetSlowOps() []map[string]interface{} { h.mu.Lock() defer h.mu.Unlock() return h.slowOps }