package zaplog import ( "fmt" "os" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" "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() + "]") } return 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 } func New(config ...Config) *zap.SugaredLogger { cfg := configDefault(config...) var encoder zapcore.Encoder if cfg.JsonFormat { encoder = zapcore.NewJSONEncoder(jsonencoderConfig()) } else { encoder = zapcore.NewConsoleEncoder(textencoderConfig()) } var coreArr []zapcore.Core // 检查并合并相同配置的写入器 wsCache := make(map[string]zapcore.WriteSyncer) // 创建核心的函数 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) // 获取或创建写入器 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 } // 创建多写入器(文件+控制台) multiWs := zapcore.NewMultiWriteSyncer(ws, zapcore.AddSync(os.Stdout)) // 创建级别过滤器 priority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { return lev == level }) return zapcore.NewCore(encoder, multiWs, priority) } // 为每个级别创建核心 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 <= DPanic { coreArr = append(coreArr, createCore(zap.DPanicLevel, cfg.DPanicLog)) } if cfg.Mode <= Panic { coreArr = append(coreArr, createCore(zap.PanicLevel, cfg.PanicLog)) } 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() }