package logger import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "io" "os" "time" ) const ( // DebugLevel logs are typically voluminous, and are usually disabled in // production. DebugLevel = zapcore.DebugLevel // InfoLevel is the default logging priority. InfoLevel = zapcore.InfoLevel // WarnLevel logs are more important than Info, but don't need individual // human review. WarnLevel = zapcore.WarnLevel // ErrorLevel logs are high-priority. If an application is running smoothly, // it shouldn't generate any error-level logs. ErrorLevel = zapcore.ErrorLevel // DPanicLevel logs are particularly important errors. In development the // logger panics after writing the message. DPanicLevel = zapcore.DPanicLevel // PanicLevel logs a message, then panics. PanicLevel = zapcore.PanicLevel // FatalLevel logs a message, then calls os.Exit(1). FatalLevel = zapcore.FatalLevel ) var ( Logger = &logger{} LowercaseLevelEncoder = zapcore.LowercaseLevelEncoder LowercaseColorLevelEncoder = zapcore.LowercaseColorLevelEncoder CapitalLevelEncoder = zapcore.CapitalLevelEncoder CapitalColorLevelEncoder = zapcore.CapitalColorLevelEncoder ) type logger struct { *zap.Logger Config *LoggerConfig hasShowLine bool } type LoggerConfig struct { Levels []zapcore.Level `json:"level"` ShowLine bool `json:"showLine"` LogInConsole bool `json:"logInConsole"` Format string `json:"format"` EncodeLevel zapcore.LevelEncoder `json:"encodeLevel"` Prefix string `json:"prefix"` Writer func(config *LoggerConfig, filename string, level zapcore.Level) io.Writer } // InitLogger @Title 初始化日志工具 func InitLogger(config *LoggerConfig) *logger { Logger.Config = config Logger.Logger = zap.New(zapcore.NewTee( Logger.getEncoderCore("debug", zapcore.DebugLevel), Logger.getEncoderCore("info", zapcore.InfoLevel), Logger.getEncoderCore("Warn", zapcore.WarnLevel), Logger.getEncoderCore("error", zapcore.ErrorLevel), ), zap.AddCaller()) if config.ShowLine { Logger.Logger = Logger.Logger.WithOptions(zap.AddCaller()) } return Logger } // getEncoderConfig 获取zapcore.EncoderConfig func (l *logger) getEncoderConfig() (config zapcore.EncoderConfig) { config = zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", TimeKey: "time", NameKey: "logger", CallerKey: "caller", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: l.Config.EncodeLevel, EncodeTime: l.CustomTimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.FullCallerEncoder, } if config.EncodeLevel == nil { config.EncodeLevel = zapcore.LowercaseLevelEncoder } return config } // getEncoder 获取zapcore.Encoder func (l *logger) getEncoder() zapcore.Encoder { if l.Config.Format == "json" { return zapcore.NewJSONEncoder(l.getEncoderConfig()) } return zapcore.NewConsoleEncoder(l.getEncoderConfig()) } // getEncoderCore 获取Encoder的zapcore.Core func (l *logger) getEncoderCore(filename string, level zapcore.Level) (core zapcore.Core) { return zapcore.NewCore(l.getEncoder(), l.getWriteSyncer(filename, level), zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return l.inLevel(level) && lvl >= level })) } func (l *logger) inLevel(level zapcore.Level) bool { for _, cLevel := range l.Config.Levels { if cLevel == level { return true } } return false } // CustomTimeEncoder 自定义日志输出时间格式 func (l *logger) CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format(l.Config.Prefix + "2006/01/02 - 15:04:05.000")) } // @author: [piexlmax](https://github.com/piexlmax) // @function: PathExists // @description: 文件目录是否存在 // @param: path string // @return: bool, error func (l *logger) pathExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } func (l *logger) getWriteSyncer(filename string, level zapcore.Level) zapcore.WriteSyncer { var fileWriter io.Writer // 日志切割 if l.Config.Writer != nil { fileWriter = l.Config.Writer(l.Config, filename, level) } else { return zapcore.AddSync(os.Stdout) } if l.Config.LogInConsole && !l.hasShowLine && l.inLevel(level) { l.hasShowLine = true return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)) } return zapcore.AddSync(fileWriter) }