From 1e65ade93fa431fb2e10b236e50f8d98ca092e27 Mon Sep 17 00:00:00 2001 From: cc Date: Fri, 2 May 2025 01:28:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96log,=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=86=99=E5=85=A5=E5=90=8C=E4=B8=80=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- log/zaplog/config.go | 130 ++++++++++------------------------- log/zaplog/zaplog.go | 159 +++++++++++++++++++++---------------------- 2 files changed, 111 insertions(+), 178 deletions(-) diff --git a/log/zaplog/config.go b/log/zaplog/config.go index dcbda86..59aee7c 100644 --- a/log/zaplog/config.go +++ b/log/zaplog/config.go @@ -11,15 +11,16 @@ const ( ) type LogFileConfig struct { - Filename string // 日志文件存放目录及名称,如果文件夹不存在会自动创建 - FileSize_MB int // 文件大小限制,单位MB - FileBackup int // 最大保留日志文件数量 + Filename string // 日志文件路径及名称(自动创建不存在的目录) + FileSize_MB int // 文件大小限制(MB) + FileBackup int // 最大保留日志文件数 FileAge_DAY int // 日志文件保留天数 + Compress bool // 是否压缩日志 } type Config struct { - JsonFormat bool // 是否使用json格式,默认false - Mode int8 // 日志启用级别 + JsonFormat bool // 是否使用JSON格式(默认false) + Mode int8 // 日志启用级别(使用上面定义的常量) DebugLog LogFileConfig // Debug日志配置 InfoLog LogFileConfig // Info日志配置 WarnLog LogFileConfig // Warn日志配置 @@ -29,107 +30,46 @@ type Config struct { var cfg_default = Config{ DebugLog: LogFileConfig{ - Filename: "./log/debug", - FileSize_MB: 5, - FileBackup: 5, - FileAge_DAY: 30, - }, - InfoLog: LogFileConfig{ - Filename: "./log/info", - FileSize_MB: 5, - FileBackup: 5, - FileAge_DAY: 30, - }, - WarnLog: LogFileConfig{ - Filename: "./log/warn", - FileSize_MB: 5, - FileBackup: 5, - FileAge_DAY: 30, - }, - ErrorLog: LogFileConfig{ - Filename: "./log/error", - FileSize_MB: 5, - FileBackup: 5, - FileAge_DAY: 30, - }, - FatalLog: LogFileConfig{ - Filename: "./log/fatal", + Filename: "./log/log", FileSize_MB: 5, FileBackup: 5, FileAge_DAY: 30, + Compress: true, }, } +// 辅助函数:应用默认值 +func applyDefaults(target, source *LogFileConfig) { + if target.Filename == "" { + target.Filename = source.Filename + } + if target.FileSize_MB == 0 { + target.FileSize_MB = source.FileSize_MB + } + if target.FileBackup == 0 { + target.FileBackup = source.FileBackup + } + if target.FileAge_DAY == 0 { + target.FileAge_DAY = source.FileAge_DAY + } + if !target.Compress && source.Compress { + target.Compress = source.Compress + } +} + func configDefault(config ...Config) Config { - if len(config) < 1 { + if len(config) == 0 { return cfg_default } + cfg := config[0] - if cfg.DebugLog.Filename == "" { - cfg.DebugLog.Filename = cfg_default.DebugLog.Filename - } - if cfg.DebugLog.FileSize_MB == 0 { - cfg.DebugLog.FileSize_MB = cfg_default.DebugLog.FileSize_MB - } - if cfg.DebugLog.FileBackup == 0 { - cfg.DebugLog.FileBackup = cfg_default.DebugLog.FileBackup - } - if cfg.DebugLog.FileAge_DAY == 0 { - cfg.DebugLog.FileAge_DAY = cfg_default.DebugLog.FileAge_DAY - } - - if cfg.InfoLog.Filename == "" { - cfg.InfoLog.Filename = cfg_default.InfoLog.Filename - } - if cfg.InfoLog.FileSize_MB == 0 { - cfg.InfoLog.FileSize_MB = cfg_default.InfoLog.FileSize_MB - } - if cfg.InfoLog.FileBackup == 0 { - cfg.InfoLog.FileBackup = cfg_default.InfoLog.FileBackup - } - if cfg.InfoLog.FileAge_DAY == 0 { - cfg.InfoLog.FileAge_DAY = cfg_default.InfoLog.FileAge_DAY - } - - if cfg.WarnLog.Filename == "" { - cfg.WarnLog.Filename = cfg_default.WarnLog.Filename - } - if cfg.WarnLog.FileSize_MB == 0 { - cfg.WarnLog.FileSize_MB = cfg_default.WarnLog.FileSize_MB - } - if cfg.WarnLog.FileBackup == 0 { - cfg.WarnLog.FileBackup = cfg_default.WarnLog.FileBackup - } - if cfg.WarnLog.FileAge_DAY == 0 { - cfg.WarnLog.FileAge_DAY = cfg_default.WarnLog.FileAge_DAY - } - - if cfg.ErrorLog.Filename == "" { - cfg.ErrorLog.Filename = cfg_default.ErrorLog.Filename - } - if cfg.ErrorLog.FileSize_MB == 0 { - cfg.ErrorLog.FileSize_MB = cfg_default.ErrorLog.FileSize_MB - } - if cfg.ErrorLog.FileBackup == 0 { - cfg.ErrorLog.FileBackup = cfg_default.ErrorLog.FileBackup - } - if cfg.ErrorLog.FileAge_DAY == 0 { - cfg.ErrorLog.FileAge_DAY = cfg_default.ErrorLog.FileAge_DAY - } - - if cfg.FatalLog.Filename == "" { - cfg.FatalLog.Filename = cfg_default.FatalLog.Filename - } - if cfg.FatalLog.FileSize_MB == 0 { - cfg.FatalLog.FileSize_MB = cfg_default.FatalLog.FileSize_MB - } - if cfg.FatalLog.FileBackup == 0 { - cfg.FatalLog.FileBackup = cfg_default.FatalLog.FileBackup - } - if cfg.FatalLog.FileAge_DAY == 0 { - cfg.FatalLog.FileAge_DAY = cfg_default.FatalLog.FileAge_DAY - } + // 为每个日志级别应用默认值 + applyDefaults(&cfg.DebugLog, &cfg_default.DebugLog) + applyDefaults(&cfg.InfoLog, &cfg_default.DebugLog) + applyDefaults(&cfg.WarnLog, &cfg_default.DebugLog) + applyDefaults(&cfg.ErrorLog, &cfg_default.DebugLog) + applyDefaults(&cfg.FatalLog, &cfg_default.DebugLog) return cfg } diff --git a/log/zaplog/zaplog.go b/log/zaplog/zaplog.go index 69e4ba2..ba3b1cd 100644 --- a/log/zaplog/zaplog.go +++ b/log/zaplog/zaplog.go @@ -1,6 +1,7 @@ package zaplog import ( + "fmt" "os" "time" @@ -9,13 +10,40 @@ import ( "gopkg.in/natefinch/lumberjack.v2" ) +// 创建全局写入器缓存 +var writeSyncerCache = make(map[string]zapcore.WriteSyncer) + +func getWriteSyncer(filename string, maxSize, maxBackups, maxAge int, compress bool) zapcore.WriteSyncer { + // 生成缓存键 + cacheKey := filename + if maxSize != 0 || maxBackups != 0 || maxAge != 0 { + cacheKey = fmt.Sprintf("%s:%d:%d:%d:%v", filename, maxSize, maxBackups, maxAge, compress) + } + + // 检查缓存 + if ws, ok := writeSyncerCache[cacheKey]; ok { + return ws + } + + // 创建新的写入器 + ws := zapcore.AddSync(&lumberjack.Logger{ + Filename: filename, + MaxSize: maxSize, + MaxBackups: maxBackups, + MaxAge: maxAge, + Compress: compress, + }) + + // 存入缓存 + writeSyncerCache[cacheKey] = ws + return ws +} + func textencoderConfig() zapcore.EncoderConfig { encoderConfig := zap.NewProductionEncoderConfig() - // 时间格式 encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + t.Format("2006-01-02 15:04:05") + "]") } - // 日志等级字母大写 encoderConfig.EncodeLevel = func(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + level.CapitalString() + "]") } @@ -24,11 +52,9 @@ func textencoderConfig() zapcore.EncoderConfig { func jsonencoderConfig() zapcore.EncoderConfig { encoderConfig := zap.NewProductionEncoderConfig() - // 时间格式 encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05")) } - // 日志等级字母大写 encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder return encoderConfig } @@ -37,97 +63,64 @@ func New(config ...Config) *zap.SugaredLogger { cfg := configDefault(config...) var encoder zapcore.Encoder - encoder = zapcore.NewConsoleEncoder(textencoderConfig()) if cfg.JsonFormat { encoder = zapcore.NewJSONEncoder(jsonencoderConfig()) + } else { + encoder = zapcore.NewConsoleEncoder(textencoderConfig()) } var coreArr []zapcore.Core - // 日志级别 Debug 级别 - DebugPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { - return lev == zap.DebugLevel - }) + // 检查并合并相同配置的写入器 + wsCache := make(map[string]zapcore.WriteSyncer) - // Debug 文件 writeSyncer - DebugFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ - Filename: cfg.DebugLog.Filename, - MaxSize: cfg.DebugLog.FileSize_MB, - MaxBackups: cfg.DebugLog.FileBackup, - MaxAge: cfg.DebugLog.FileAge_DAY, - Compress: true, - }) + // 创建核心的函数 + createCore := func(level zapcore.Level, logConfig LogFileConfig) zapcore.Core { + // 生成缓存键 + cacheKey := fmt.Sprintf("%s:%d:%d:%d:%v", logConfig.Filename, logConfig.FileSize_MB, logConfig.FileBackup, logConfig.FileAge_DAY, true) - DebugFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(DebugFileWriteSyncer, zapcore.AddSync(os.Stdout)), DebugPriority) - coreArr = append(coreArr, DebugFileCore) + // 获取或创建写入器 + var ws zapcore.WriteSyncer + if existingWs, ok := wsCache[cacheKey]; ok { + ws = existingWs + } else { + ws = getWriteSyncer( + logConfig.Filename, + logConfig.FileSize_MB, + logConfig.FileBackup, + logConfig.FileAge_DAY, + true, + ) + wsCache[cacheKey] = ws + } - // 日志级别 Info 级别 - InfoPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { - return lev == zap.InfoLevel - }) + // 创建多写入器(文件+控制台) + multiWs := zapcore.NewMultiWriteSyncer(ws, zapcore.AddSync(os.Stdout)) - // Info 文件 writeSyncer - InfoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ - Filename: cfg.InfoLog.Filename, - MaxSize: cfg.InfoLog.FileSize_MB, - MaxBackups: cfg.InfoLog.FileBackup, - MaxAge: cfg.InfoLog.FileAge_DAY, - Compress: true, - }) + // 创建级别过滤器 + priority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { + return lev == level + }) - InfoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(InfoFileWriteSyncer, zapcore.AddSync(os.Stdout)), InfoPriority) - coreArr = append(coreArr, InfoFileCore) + return zapcore.NewCore(encoder, multiWs, priority) + } - // 日志级别 Warn 级别 - WarnPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { - return lev == zap.WarnLevel - }) - - // Warn 文件 writeSyncer - WarnFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ - Filename: cfg.WarnLog.Filename, - MaxSize: cfg.WarnLog.FileSize_MB, - MaxBackups: cfg.WarnLog.FileBackup, - MaxAge: cfg.WarnLog.FileAge_DAY, - Compress: true, - }) - - WarnFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(WarnFileWriteSyncer, zapcore.AddSync(os.Stdout)), WarnPriority) - coreArr = append(coreArr, WarnFileCore) - - // 日志级别 Error 级别 - ErrorPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { - return lev == zap.ErrorLevel - }) - - // Error 文件 writeSyncer - ErrorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ - Filename: cfg.ErrorLog.Filename, - MaxSize: cfg.ErrorLog.FileSize_MB, - MaxBackups: cfg.ErrorLog.FileBackup, - MaxAge: cfg.ErrorLog.FileAge_DAY, - Compress: true, - }) - - ErrorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(ErrorFileWriteSyncer, zapcore.AddSync(os.Stdout)), ErrorPriority) - coreArr = append(coreArr, ErrorFileCore) - - // 日志级别 DPanic\Panic\Fatal 级别 - HighPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { - return lev >= zap.DPanicLevel - }) - - // High 文件 writeSyncer - HighFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ - Filename: cfg.FatalLog.Filename, - MaxSize: cfg.FatalLog.FileSize_MB, - MaxBackups: cfg.FatalLog.FileBackup, - MaxAge: cfg.FatalLog.FileAge_DAY, - Compress: true, - }) - - HighFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(HighFileWriteSyncer, zapcore.AddSync(os.Stdout)), HighPriority) - coreArr = append(coreArr, HighFileCore) + // 为每个级别创建核心 + if cfg.Mode <= Debug { + coreArr = append(coreArr, createCore(zap.DebugLevel, cfg.DebugLog)) + } + if cfg.Mode <= Info { + coreArr = append(coreArr, createCore(zap.InfoLevel, cfg.InfoLog)) + } + if cfg.Mode <= Warn { + coreArr = append(coreArr, createCore(zap.WarnLevel, cfg.WarnLog)) + } + if cfg.Mode <= Error { + coreArr = append(coreArr, createCore(zap.ErrorLevel, cfg.ErrorLog)) + } + if cfg.Mode <= Fatal { + coreArr = append(coreArr, createCore(zap.FatalLevel, cfg.FatalLog)) + } return zap.New(zapcore.NewTee(coreArr...), zap.IncreaseLevel(zapcore.Level(cfg.Mode))).Sugar() }