package log import ( "io" "os" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) var ( _logger *zap.Logger ) const ( // FormatText format log text FormatText = "text" // FormatJSON format log json FormatJSON = "json" ) // type Level uint // 日志配置 type logConfig struct { LogPath string LogLevel string Compress bool MaxSize int MaxAge int MaxBackups int Format string } func getzapLevel(level string) zapcore.Level { switch level { case "debug": return zap.DebugLevel case "info": return zap.InfoLevel case "warn": return zap.WarnLevel case "error": return zap.ErrorLevel case "panic": return zap.PanicLevel case "fatal": return zap.FatalLevel default: return zap.InfoLevel } } func newLogWriter(logpath string, maxsize int, compress bool) io.Writer { if logpath == "" || logpath == "-" { return os.Stdout } return &lumberjack.Logger{ Filename: logpath, MaxSize: maxsize, Compress: compress, } } func newZapEncoder() zapcore.EncoderConfig { encoderConfig := zapcore.EncoderConfig{ TimeKey: "time", LevelKey: "level", NameKey: "logger", CallerKey: "line", MessageKey: "msg", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, // 小写编码器 EncodeTime: zapcore.ISO8601TimeEncoder, // ISO8601 UTC 时间格式 EncodeDuration: zapcore.SecondsDurationEncoder, // EncodeCaller: zapcore.ShortCallerEncoder, // 全路径编码器 EncodeName: zapcore.FullNameEncoder, } return encoderConfig } func newLoggerCore(log *logConfig) zapcore.Core { hook := newLogWriter(log.LogPath, log.MaxSize, log.Compress) encoderConfig := newZapEncoder() atomLevel := zap.NewAtomicLevelAt(getzapLevel(log.LogLevel)) var encoder zapcore.Encoder if log.Format == FormatJSON { encoder = zapcore.NewJSONEncoder(encoderConfig) } else { encoder = zapcore.NewConsoleEncoder(encoderConfig) } core := zapcore.NewCore( encoder, zapcore.NewMultiWriteSyncer(zapcore.AddSync(hook)), atomLevel, ) return core } func newLoggerOptions() []zap.Option { // 开启开发模式,堆栈跟踪 caller := zap.AddCaller() callerskip := zap.AddCallerSkip(1) // 开发者 development := zap.Development() options := []zap.Option{ caller, callerskip, development, } return options } // Option function option type Option func(*logConfig) // Path set logpath // if is zero will print,or write file func Path(logpath string) Option { return func(logcfg *logConfig) { logcfg.LogPath = logpath } } // Compress compress log func Compress(compress bool) Option { return func(logcfg *logConfig) { logcfg.Compress = compress } } // Level set log level default info func Level(level string) Option { return func(logcfg *logConfig) { logcfg.LogLevel = level } } // MaxSize Log Max Size func MaxSize(size int) Option { return func(logcfg *logConfig) { logcfg.MaxSize = size } } // MaxAge log store day func MaxAge(age int) Option { return func(logcfg *logConfig) { logcfg.MaxAge = age } } // MaxBackups total store log func MaxBackups(backup int) Option { return func(logcfg *logConfig) { logcfg.MaxBackups = backup } } // Format log json or text func Format(format string) Option { return func(logcfg *logConfig) { if format == FormatJSON { logcfg.Format = FormatJSON } else { logcfg.Format = FormatText } } } func defaultOption() *logConfig { return &logConfig{ LogPath: "", MaxSize: 20, Compress: true, MaxAge: 7, MaxBackups: 7, LogLevel: "debug", Format: FormatText, } } // InitLog conf func InitLog(opts ...Option) error { logcfg := defaultOption() for _, opt := range opts { opt(logcfg) } core := newLoggerCore(logcfg) zapopts := newLoggerOptions() _logger = zap.New(core, zapopts...) return nil } // Debug output log func Debug(msg string, fields ...zap.Field) { _logger.Debug(msg, fields...) } // Info output log func Info(msg string, fields ...zap.Field) { _logger.Info(msg, fields...) } // Warn output log func Warn(msg string, fields ...zap.Field) { _logger.Warn(msg, fields...) } // Error output log func Error(msg string, fields ...zap.Field) { _logger.Error(msg, fields...) } // Panic output panic func Panic(msg string, fields ...zap.Field) { _logger.Panic(msg, fields...) } // Fatal output log func Fatal(msg string, fields ...zap.Field) { _logger.Fatal(msg, fields...) }