package logger import ( cfg "MeterService/core/config" "errors" "io" "log" "sync" "time" rotatelogs "github.com/lestrrat-go/file-rotatelogs" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var ( Logger *zap.Logger loggerMu sync.Mutex ) func init() { err := InitLogger() if err != nil { log.Println("logger初始化失败") panic(err) } } func InitLogger() error { loggerMu.Lock() defer loggerMu.Unlock() config := getConfig() encoder := createEncoder(config.LogType) logLevel := getLogLevel(config.Level) var cores []zapcore.Core switch config.FileType { case "level": debugCore := zapcore.NewCore(encoder, zapcore.AddSync(getLoggerWriter("debug", config.FileFormat)), zap.DebugLevel) infoCore := zapcore.NewCore(encoder, zapcore.AddSync(getLoggerWriter("info", config.FileFormat)), zap.InfoLevel) errorCore := zapcore.NewCore(encoder, zapcore.AddSync(getLoggerWriter("error", config.FileFormat)), zap.ErrorLevel) cores = append(cores, debugCore, infoCore, errorCore) default: core := zapcore.NewCore(encoder, zapcore.AddSync(getLoggerWriter("all", config.FileFormat)), logLevel) cores = append(cores, core) } core := zapcore.NewTee(cores...) newLogger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.WarnLevel)) if newLogger == nil { return errors.New("failed to initialize logger") } Logger = newLogger return nil } func getConfig() *cfg.LoggerConfig { return &cfg.C.Logger } func createEncoder(logType string) zapcore.Encoder { config := zapcore.EncoderConfig{ TimeKey: "ts", LevelKey: "level", MessageKey: "msg", EncodeTime: customEncodeTime, EncodeDuration: customEncodeDuration, EncodeCaller: zapcore.ShortCallerEncoder, } if logType == "json" { return zapcore.NewJSONEncoder(config) } return zapcore.NewConsoleEncoder(config) } func getLogLevel(level string) zapcore.Level { var logLevel zapcore.Level switch level { case "debug": logLevel = zap.DebugLevel case "info": logLevel = zap.InfoLevel case "error": logLevel = zap.ErrorLevel default: logLevel = zap.InfoLevel // 默认日志级别 } return logLevel } func getLoggerWriter(filename, fileFormat string) io.Writer { filePath, saveDay := "./logs", 30 if cfg.C.Logger.FilePath != "" { filePath = cfg.C.Logger.FilePath } if cfg.C.Logger.MaxSaveDays > 0 { saveDay = cfg.C.Logger.MaxSaveDays } filename = filePath + "/" + filename // 日志切割 hook, err := rotatelogs.New( filename+"/"+fileFormat+".log", //rotatelogs.WithLinkName(filename), rotatelogs.WithMaxAge(time.Duration(saveDay)*24*time.Hour), rotatelogs.WithRotationTime(24*time.Hour), ) if err != nil { log.Printf("日志启动异常: %v\n", err) return nil } return hook } func customEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05")) } func customEncodeDuration(duration time.Duration, encoder zapcore.PrimitiveArrayEncoder) { encoder.AppendInt64(int64(duration) / 100000000) // nano -> milli } func Debug(format string, v ...interface{}) { if cfg.C.Vber.Mode == "debug" { if v == nil { Logger.Sugar().Debug(format) } else { Logger.Sugar().Debugf(format, v...) } } } func Info(format string, v ...interface{}) { if v == nil { Logger.Sugar().Info(format) } else { Logger.Sugar().Infof(format, v...) } } func Error(format string, v ...interface{}) { if v == nil { Logger.Sugar().Error(format) } else { Logger.Sugar().Errorf(format, v...) } }