package logger import ( "encoding/json" "fmt" "strings" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) type ZapConfig struct { Level zap.AtomicLevel `json:"level" yaml:"level"` Development bool `json:"development" yaml:"development"` DisableCaller bool `json:"disableCaller" yaml:"disableCaller"` DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"` Encoding string `json:"encoding" yaml:"encoding"` OutputPath string `json:"outputPath" yaml:"outputPath"` } // init log func InitLogger(runmode, logPath string, maxSize, maxBackups, maxAge int, disableStacktrace bool) *zap.Logger { level := "debug" encoding := "json" development := true if runmode == "prod" { level = "info" development = false } js := fmt.Sprintf(`{ "level": "%s", "encoding": "%s", "outputPath": "%s" }`, level, encoding, logPath) var zcfg ZapConfig if err := json.Unmarshal([]byte(js), &zcfg); err != nil { panic(err) } zcfg.Development = development zcfg.DisableStacktrace = disableStacktrace return zcfg.New(maxSize, maxBackups, maxAge) } func NewInfoLogger(runmode, logPath string, maxSize, maxBackups, maxAge int) *zap.Logger { level := "info" encoding := "json" development := true if runmode == "prod" { development = false } js := fmt.Sprintf(`{ "level": "%s", "encoding": "%s", "outputPath": "%s" }`, level, encoding, logPath) var zcfg ZapConfig if err := json.Unmarshal([]byte(js), &zcfg); err != nil { panic(err) } zcfg.Development = development zcfg.DisableStacktrace = true return zcfg.New(maxSize, maxBackups, maxAge) } func (zc *ZapConfig) New(maxSize, maxBackups, maxAge int) *zap.Logger { // if nil, default the values if maxSize == 0 { maxSize = 100 } if maxBackups == 0 { maxBackups = 7 } if maxAge == 0 { maxAge = 30 } hook := lumberjack.Logger{ Filename: zc.OutputPath, MaxSize: maxSize, // megabytes MaxBackups: maxBackups, // backups number MaxAge: maxAge, // days Compress: true, // disabled by default } fileWriter := zapcore.AddSync(&hook) var EncoderConfig zapcore.EncoderConfig if zc.Development { EncoderConfig = zap.NewDevelopmentEncoderConfig() } else { EncoderConfig = zap.NewProductionEncoderConfig() } // 自定义 EncoderConfig.EncodeTime = CustomTimeEncoder var encoder zapcore.Encoder if strings.ToLower(zc.Encoding) == "console" { encoder = zapcore.NewConsoleEncoder(EncoderConfig) } else { encoder = zapcore.NewJSONEncoder(EncoderConfig) } core := zapcore.NewCore(encoder, fileWriter, zc.Level) opts := zc.buildOptions(fileWriter) return zap.New(core, opts...) } func (zc *ZapConfig) buildOptions(fileWriter zapcore.WriteSyncer) []zap.Option { opts := []zap.Option{zap.ErrorOutput(fileWriter)} if !zc.DisableCaller { opts = append(opts, zap.AddCaller()) } if !zc.DisableStacktrace { stackLevel := zap.ErrorLevel if zc.Development { stackLevel = zap.WarnLevel } opts = append(opts, zap.AddStacktrace(stackLevel)) } return opts } // 自定义时间格式 func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) }