| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | package logger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							|  |  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2025-07-28 13:47:58 +08:00
										 |  |  |  | 	"path/filepath" | 
					
						
							|  |  |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	"go.uber.org/zap" | 
					
						
							|  |  |  |  | 	"go.uber.org/zap/zapcore" | 
					
						
							| 
									
										
										
										
											2025-07-28 13:47:58 +08:00
										 |  |  |  | 	"gopkg.in/natefinch/lumberjack.v2" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // Logger 日志器接口 - 基于 Zap 官方推荐 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | type Logger interface { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 基础日志方法 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	Debug(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 	Info(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 	Warn(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 	Error(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 	Fatal(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 	Panic(msg string, fields ...zapcore.Field) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 结构化日志方法 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	With(fields ...zapcore.Field) Logger | 
					
						
							|  |  |  |  | 	WithContext(ctx context.Context) Logger | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	Named(name string) Logger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 同步和清理 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	Sync() error | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	Core() zapcore.Core | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 获取原生 Zap Logger(用于高级功能) | 
					
						
							|  |  |  |  | 	GetZapLogger() *zap.Logger | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // Config 日志配置 - 基于 Zap 官方配置结构 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | type Config struct { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 基础配置 | 
					
						
							|  |  |  |  | 	Level      string `mapstructure:"level"`       // 日志级别 | 
					
						
							|  |  |  |  | 	Format     string `mapstructure:"format"`      // 输出格式 (json/console) | 
					
						
							|  |  |  |  | 	Output     string `mapstructure:"output"`      // 输出方式 (stdout/stderr/file) | 
					
						
							|  |  |  |  | 	LogDir     string `mapstructure:"log_dir"`     // 日志目录 | 
					
						
							|  |  |  |  | 	UseDaily   bool   `mapstructure:"use_daily"`   // 是否按日分包 | 
					
						
							|  |  |  |  | 	UseColor   bool   `mapstructure:"use_color"`   // 是否使用彩色输出(仅console格式) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 文件配置 | 
					
						
							|  |  |  |  | 	MaxSize    int  `mapstructure:"max_size"`     // 单个文件最大大小(MB) | 
					
						
							|  |  |  |  | 	MaxBackups int  `mapstructure:"max_backups"`  // 最大备份文件数 | 
					
						
							|  |  |  |  | 	MaxAge     int  `mapstructure:"max_age"`      // 最大保留天数 | 
					
						
							|  |  |  |  | 	Compress   bool `mapstructure:"compress"`     // 是否压缩 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 高级功能 | 
					
						
							|  |  |  |  | 	EnableLevelSeparation bool                       `mapstructure:"enable_level_separation"` // 是否启用按级别分文件 | 
					
						
							|  |  |  |  | 	LevelConfigs          map[string]interface{}    `mapstructure:"level_configs"`           // 各级别配置(使用 interface{} 避免循环依赖) | 
					
						
							|  |  |  |  | 	EnableRequestLogging  bool                       `mapstructure:"enable_request_logging"`  // 是否启用请求日志 | 
					
						
							|  |  |  |  | 	EnablePerformanceLog  bool                       `mapstructure:"enable_performance_log"`  // 是否启用性能日志 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 开发环境配置 | 
					
						
							|  |  |  |  | 	Development bool `mapstructure:"development"` // 是否为开发环境 | 
					
						
							|  |  |  |  | 	Sampling    bool `mapstructure:"sampling"`    // 是否启用采样 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ZapLogger Zap日志实现 - 基于官方推荐 | 
					
						
							|  |  |  |  | type ZapLogger struct { | 
					
						
							|  |  |  |  | 	logger *zap.Logger | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // NewLogger 创建新的日志实例 - 使用 Zap 官方推荐的方式 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | func NewLogger(config Config) (Logger, error) { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	var logger *zap.Logger | 
					
						
							|  |  |  |  | 	var err error | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 根据环境创建合适的日志器 | 
					
						
							|  |  |  |  | 	if config.Development { | 
					
						
							|  |  |  |  | 		logger, err = zap.NewDevelopment( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 	} else { | 
					
						
							|  |  |  |  | 		logger, err = zap.NewProduction( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 如果配置为文件输出,需要手动设置 Core | 
					
						
							|  |  |  |  | 	if config.Output == "file" { | 
					
						
							|  |  |  |  | 		writeSyncer, err := createFileWriteSyncer(config) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 			return nil, err | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		 | 
					
						
							|  |  |  |  | 		// 创建新的 Core 并替换 | 
					
						
							|  |  |  |  | 		encoder := getEncoder(config.Format, config) | 
					
						
							|  |  |  |  | 		level := getLogLevel(config.Level) | 
					
						
							|  |  |  |  | 		core := zapcore.NewCore(encoder, writeSyncer, level) | 
					
						
							|  |  |  |  | 		logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1), zap.AddStacktrace(zapcore.ErrorLevel)) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return &ZapLogger{ | 
					
						
							|  |  |  |  | 		logger: logger, | 
					
						
							|  |  |  |  | 	}, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // 实现 Logger 接口 | 
					
						
							|  |  |  |  | func (z *ZapLogger) Debug(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Debug(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-07-28 13:47:58 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Info(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Info(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Warn(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Warn(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Error(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Error(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Fatal(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Fatal(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Panic(msg string, fields ...zapcore.Field) { | 
					
						
							|  |  |  |  | 	z.logger.Panic(msg, fields...) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) With(fields ...zapcore.Field) Logger { | 
					
						
							|  |  |  |  | 	return &ZapLogger{logger: z.logger.With(fields...)} | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) WithContext(ctx context.Context) Logger { | 
					
						
							|  |  |  |  | 	// 从上下文提取字段 | 
					
						
							|  |  |  |  | 	fields := extractFieldsFromContext(ctx) | 
					
						
							|  |  |  |  | 	return &ZapLogger{logger: z.logger.With(fields...)} | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Named(name string) Logger { | 
					
						
							|  |  |  |  | 	return &ZapLogger{logger: z.logger.Named(name)} | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Sync() error { | 
					
						
							|  |  |  |  | 	return z.logger.Sync() | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) Core() zapcore.Core { | 
					
						
							|  |  |  |  | 	return z.logger.Core() | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func (z *ZapLogger) GetZapLogger() *zap.Logger { | 
					
						
							|  |  |  |  | 	return z.logger | 
					
						
							| 
									
										
										
										
											2025-07-13 16:36:20 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // 全局日志器 - 基于 Zap 官方推荐 | 
					
						
							|  |  |  |  | var globalLogger *zap.Logger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // InitGlobalLogger 初始化全局日志器 | 
					
						
							|  |  |  |  | func InitGlobalLogger(config Config) error { | 
					
						
							|  |  |  |  | 	var logger *zap.Logger | 
					
						
							|  |  |  |  | 	var err error | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 根据环境创建合适的日志器 | 
					
						
							|  |  |  |  | 	if config.Development { | 
					
						
							|  |  |  |  | 		logger, err = zap.NewDevelopment( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 	} else { | 
					
						
							|  |  |  |  | 		logger, err = zap.NewProduction( | 
					
						
							|  |  |  |  | 			zap.AddCaller(), | 
					
						
							|  |  |  |  | 			zap.AddCallerSkip(1), | 
					
						
							|  |  |  |  | 			zap.AddStacktrace(zapcore.ErrorLevel), | 
					
						
							|  |  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 	// 如果配置为文件输出,需要手动设置 Core | 
					
						
							|  |  |  |  | 	if config.Output == "file" { | 
					
						
							|  |  |  |  | 		writeSyncer, err := createFileWriteSyncer(config) | 
					
						
							|  |  |  |  | 		if err != nil { | 
					
						
							|  |  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 		 | 
					
						
							|  |  |  |  | 		// 创建新的 Core 并替换 | 
					
						
							|  |  |  |  | 		encoder := getEncoder(config.Format, config) | 
					
						
							|  |  |  |  | 		level := getLogLevel(config.Level) | 
					
						
							|  |  |  |  | 		core := zapcore.NewCore(encoder, writeSyncer, level) | 
					
						
							|  |  |  |  | 		logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1), zap.AddStacktrace(zapcore.ErrorLevel)) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 替换全局日志器 | 
					
						
							|  |  |  |  | 	zap.ReplaceGlobals(logger) | 
					
						
							|  |  |  |  | 	globalLogger = logger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // GetGlobalLogger 获取全局日志器 | 
					
						
							|  |  |  |  | func GetGlobalLogger() *zap.Logger { | 
					
						
							|  |  |  |  | 	if globalLogger == nil { | 
					
						
							|  |  |  |  | 		// 如果没有初始化,使用默认的生产环境配置 | 
					
						
							|  |  |  |  | 		globalLogger = zap.Must(zap.NewProduction()) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return globalLogger | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // L 获取全局日志器(Zap 官方推荐的方式) | 
					
						
							|  |  |  |  | func L() *zap.Logger { | 
					
						
							|  |  |  |  | 	return zap.L() | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | // 辅助函数 | 
					
						
							|  |  |  |  | func getLogLevel(level string) zapcore.Level { | 
					
						
							|  |  |  |  | 	switch level { | 
					
						
							|  |  |  |  | 	case "debug": | 
					
						
							|  |  |  |  | 		return zapcore.DebugLevel | 
					
						
							|  |  |  |  | 	case "info": | 
					
						
							|  |  |  |  | 		return zapcore.InfoLevel | 
					
						
							|  |  |  |  | 	case "warn": | 
					
						
							|  |  |  |  | 		return zapcore.WarnLevel | 
					
						
							|  |  |  |  | 	case "error": | 
					
						
							|  |  |  |  | 		return zapcore.ErrorLevel | 
					
						
							|  |  |  |  | 	case "fatal": | 
					
						
							|  |  |  |  | 		return zapcore.FatalLevel | 
					
						
							|  |  |  |  | 	case "panic": | 
					
						
							|  |  |  |  | 		return zapcore.PanicLevel | 
					
						
							|  |  |  |  | 	default: | 
					
						
							|  |  |  |  | 		return zapcore.InfoLevel | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func getEncoder(format string, config Config) zapcore.Encoder { | 
					
						
							|  |  |  |  | 	encoderConfig := getEncoderConfig(config) | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	if format == "console" { | 
					
						
							|  |  |  |  | 		return zapcore.NewConsoleEncoder(encoderConfig) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	return zapcore.NewJSONEncoder(encoderConfig) | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func getEncoderConfig(config Config) zapcore.EncoderConfig { | 
					
						
							|  |  |  |  | 	encoderConfig := zap.NewProductionEncoderConfig() | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	if config.Development { | 
					
						
							|  |  |  |  | 		encoderConfig = zap.NewDevelopmentEncoderConfig() | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 自定义时间格式 | 
					
						
							|  |  |  |  | 	encoderConfig.TimeKey = "timestamp" | 
					
						
							|  |  |  |  | 	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 自定义级别格式 | 
					
						
							|  |  |  |  | 	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 自定义调用者格式 | 
					
						
							|  |  |  |  | 	encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	return encoderConfig | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func createFileWriteSyncer(config Config) (zapcore.WriteSyncer, error) { | 
					
						
							|  |  |  |  | 	// 使用 lumberjack 进行日志轮转 | 
					
						
							|  |  |  |  | 	rotator := &lumberjack.Logger{ | 
					
						
							|  |  |  |  | 		Filename:   getLogFilePath(config), | 
					
						
							|  |  |  |  | 		MaxSize:    config.MaxSize, | 
					
						
							|  |  |  |  | 		MaxBackups: config.MaxBackups, | 
					
						
							|  |  |  |  | 		MaxAge:     config.MaxAge, | 
					
						
							|  |  |  |  | 		Compress:   config.Compress, | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	return zapcore.AddSync(rotator), nil | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func getLogFilePath(config Config) string { | 
					
						
							|  |  |  |  | 	if config.UseDaily { | 
					
						
							|  |  |  |  | 		// 按日期分包 | 
					
						
							|  |  |  |  | 		date := time.Now().Format("2006-01-02") | 
					
						
							|  |  |  |  | 		return filepath.Join(config.LogDir, date, "app.log") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	return filepath.Join(config.LogDir, "app.log") | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-25 15:44:06 +08:00
										 |  |  |  | func extractFieldsFromContext(ctx context.Context) []zapcore.Field { | 
					
						
							|  |  |  |  | 	var fields []zapcore.Field | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 提取请求ID | 
					
						
							|  |  |  |  | 	if requestID := ctx.Value("request_id"); requestID != nil { | 
					
						
							|  |  |  |  | 		if id, ok := requestID.(string); ok { | 
					
						
							|  |  |  |  | 			fields = append(fields, zap.String("request_id", id)) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 提取用户ID | 
					
						
							|  |  |  |  | 	if userID := ctx.Value("user_id"); userID != nil { | 
					
						
							|  |  |  |  | 		if id, ok := userID.(string); ok { | 
					
						
							|  |  |  |  | 			fields = append(fields, zap.String("user_id", id)) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	// 提取跟踪ID | 
					
						
							|  |  |  |  | 	if traceID := ctx.Value("trace_id"); traceID != nil { | 
					
						
							|  |  |  |  | 		if id, ok := traceID.(string); ok { | 
					
						
							|  |  |  |  | 			fields = append(fields, zap.String("trace_id", id)) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	return fields | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | } |