| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | package logger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							|  |  |  |  | 	"context" | 
					
						
							|  |  |  |  | 	"path/filepath" | 
					
						
							|  |  |  |  | 	"time" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	"go.uber.org/zap" | 
					
						
							|  |  |  |  | 	"go.uber.org/zap/zapcore" | 
					
						
							|  |  |  |  | 	"gopkg.in/natefinch/lumberjack.v2" | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // LevelLogger 级别分文件日志器 - 基于 Zap 官方推荐 | 
					
						
							|  |  |  |  | type LevelLogger struct { | 
					
						
							|  |  |  |  | 	logger        *zap.Logger | 
					
						
							|  |  |  |  | 	levelLoggers  map[zapcore.Level]*zap.Logger | 
					
						
							|  |  |  |  | 	config        LevelLoggerConfig | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // LevelLoggerConfig 级别分文件日志器配置 | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | type LevelLoggerConfig struct { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	BaseConfig            Config | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	EnableLevelSeparation bool | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	LevelConfigs          map[zapcore.Level]LevelFileConfig | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // LevelFileConfig 单个级别文件配置 | 
					
						
							|  |  |  |  | type LevelFileConfig struct { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	MaxSize    int  `mapstructure:"max_size"` | 
					
						
							|  |  |  |  | 	MaxBackups int  `mapstructure:"max_backups"` | 
					
						
							|  |  |  |  | 	MaxAge     int  `mapstructure:"max_age"` | 
					
						
							|  |  |  |  | 	Compress   bool `mapstructure:"compress"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // NewLevelLogger 创建级别分文件日志器 | 
					
						
							|  |  |  |  | func NewLevelLogger(config LevelLoggerConfig) (Logger, error) { | 
					
						
							|  |  |  |  | 	// 根据环境创建基础日志器 | 
					
						
							|  |  |  |  | 	var baseLogger *zap.Logger | 
					
						
							|  |  |  |  | 	var err error | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if config.BaseConfig.Development { | 
					
						
							|  |  |  |  | 		baseLogger, err = zap.NewDevelopment( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 	} else { | 
					
						
							|  |  |  |  | 		baseLogger, err = zap.NewProduction( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 创建级别分文件的日志器 | 
					
						
							|  |  |  |  | 	levelLogger := &LevelLogger{ | 
					
						
							|  |  |  |  | 		logger:       baseLogger, | 
					
						
							|  |  |  |  | 		levelLoggers: make(map[zapcore.Level]*zap.Logger), | 
					
						
							|  |  |  |  | 		config:       config, | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 为每个级别创建专门的日志器 | 
					
						
							|  |  |  |  | 	if config.EnableLevelSeparation { | 
					
						
							|  |  |  |  | 		levelLogger.createLevelLoggers() | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	return levelLogger, nil | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // createLevelLoggers 创建各级别的日志器 | 
					
						
							|  |  |  |  | func (l *LevelLogger) createLevelLoggers() { | 
					
						
							|  |  |  |  | 	levels := []zapcore.Level{ | 
					
						
							|  |  |  |  | 		zapcore.DebugLevel, | 
					
						
							|  |  |  |  | 		zapcore.InfoLevel, | 
					
						
							|  |  |  |  | 		zapcore.WarnLevel, | 
					
						
							|  |  |  |  | 		zapcore.ErrorLevel, | 
					
						
							|  |  |  |  | 		zapcore.FatalLevel, | 
					
						
							|  |  |  |  | 		zapcore.PanicLevel, | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	for _, level := range levels { | 
					
						
							|  |  |  |  | 		// 获取该级别的配置 | 
					
						
							|  |  |  |  | 		levelConfig, exists := l.config.LevelConfigs[level] | 
					
						
							|  |  |  |  | 		if !exists { | 
					
						
							|  |  |  |  | 			// 如果没有配置,使用默认配置 | 
					
						
							|  |  |  |  | 			levelConfig = LevelFileConfig{ | 
					
						
							|  |  |  |  | 				MaxSize:    100, | 
					
						
							|  |  |  |  | 				MaxBackups: 5, | 
					
						
							|  |  |  |  | 				MaxAge:     30, | 
					
						
							|  |  |  |  | 				Compress:   true, | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		// 创建该级别的文件输出 | 
					
						
							|  |  |  |  | 		writeSyncer := l.createLevelWriteSyncer(level, levelConfig) | 
					
						
							|  |  |  |  | 		 | 
					
						
							|  |  |  |  | 		// 创建编码器 | 
					
						
							|  |  |  |  | 		encoder := getEncoder(l.config.BaseConfig.Format, l.config.BaseConfig) | 
					
						
							|  |  |  |  | 		 | 
					
						
							|  |  |  |  | 		// 创建 Core | 
					
						
							|  |  |  |  | 		core := zapcore.NewCore(encoder, writeSyncer, level) | 
					
						
							|  |  |  |  | 		 | 
					
						
							|  |  |  |  | 		// 创建该级别的日志器 | 
					
						
							|  |  |  |  | 		levelLogger := zap.New(core, | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		l.levelLoggers[level] = levelLogger | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // createLevelWriteSyncer 创建级别特定的文件输出同步器 | 
					
						
							|  |  |  |  | func (l *LevelLogger) createLevelWriteSyncer(level zapcore.Level, config LevelFileConfig) zapcore.WriteSyncer { | 
					
						
							|  |  |  |  | 	// 构建文件路径 | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	var logFilePath string | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if l.config.BaseConfig.UseDaily { | 
					
						
							|  |  |  |  | 		// 按日期分包:logs/2024-01-01/debug.log | 
					
						
							|  |  |  |  | 		date := time.Now().Format("2006-01-02") | 
					
						
							|  |  |  |  | 		levelName := level.String() | 
					
						
							|  |  |  |  | 		logFilePath = filepath.Join(l.config.BaseConfig.LogDir, date, levelName+".log") | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		// 传统方式:logs/debug.log | 
					
						
							|  |  |  |  | 		levelName := level.String() | 
					
						
							|  |  |  |  | 		logFilePath = filepath.Join(l.config.BaseConfig.LogDir, levelName+".log") | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 创建 lumberjack 日志轮转器 | 
					
						
							|  |  |  |  | 	rotator := &lumberjack.Logger{ | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		Filename:   logFilePath, | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		MaxSize:    config.MaxSize, | 
					
						
							|  |  |  |  | 		MaxBackups: config.MaxBackups, | 
					
						
							|  |  |  |  | 		MaxAge:     config.MaxAge, | 
					
						
							|  |  |  |  | 		Compress:   config.Compress, | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	return zapcore.AddSync(rotator) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetLevelLogger 获取指定级别的日志器 | 
					
						
							|  |  |  |  | func (l *LevelLogger) GetLevelLogger(level zapcore.Level) *zap.Logger { | 
					
						
							|  |  |  |  | 	if logger, exists := l.levelLoggers[level]; exists { | 
					
						
							|  |  |  |  | 		return logger | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return l.logger | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // 实现 Logger 接口 | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | func (l *LevelLogger) Debug(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.DebugLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Debug(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Info(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.InfoLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Info(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Warn(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.WarnLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Warn(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Error(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.ErrorLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Error(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Fatal(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.FatalLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Fatal(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Panic(msg string, fields ...zapcore.Field) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if logger := l.GetLevelLogger(zapcore.PanicLevel); logger != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		logger.Panic(msg, fields...) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) With(fields ...zapcore.Field) Logger { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 为所有级别添加字段 | 
					
						
							|  |  |  |  | 	for level, logger := range l.levelLoggers { | 
					
						
							|  |  |  |  | 		l.levelLoggers[level] = logger.With(fields...) | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	return l | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) WithContext(ctx context.Context) Logger { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 从上下文提取字段 | 
					
						
							|  |  |  |  | 	fields := extractFieldsFromContext(ctx) | 
					
						
							|  |  |  |  | 	return l.With(fields...) | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (l *LevelLogger) Named(name string) Logger { | 
					
						
							|  |  |  |  | 	// 为所有级别添加名称 | 
					
						
							|  |  |  |  | 	for level, logger := range l.levelLoggers { | 
					
						
							|  |  |  |  | 		l.levelLoggers[level] = logger.Named(name) | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	return l | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (l *LevelLogger) Sync() error { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 同步所有级别的日志器 | 
					
						
							|  |  |  |  | 	for _, logger := range l.levelLoggers { | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		if err := logger.Sync(); err != nil { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	return l.logger.Sync() | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (l *LevelLogger) Core() zapcore.Core { | 
					
						
							|  |  |  |  | 	return l.logger.Core() | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (l *LevelLogger) GetZapLogger() *zap.Logger { | 
					
						
							|  |  |  |  | 	return l.logger | 
					
						
							| 
									
										
										
										
											2025-07-28 15:21:37 +08:00
										 |  |  |  | } |