package log import ( "fmt" "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) var ( defaultLog *SLogger defLevel = zapcore.InfoLevel defMaxSize = 10 defMaxAge = 30 defMaxBackups = 360 defCompressing = true levelMap = map[string]zapcore.Level{ "trace": zapcore.DebugLevel, "debug": zapcore.DebugLevel, "info": zapcore.InfoLevel, "warning": zapcore.WarnLevel, "error": zapcore.ErrorLevel, "panic": zapcore.PanicLevel, "fatal": zapcore.FatalLevel, } ) type SLoggerOption func(*SLogger) func WithSinks(sinks ...zap.Sink) SLoggerOption { return func(l *SLogger) { l.sinks = sinks } } func WithConsole(console bool) SLoggerOption { return func(l *SLogger) { l.console = console } } func WithCompress(compress bool) SLoggerOption { return func(l *SLogger) { l.settings.Compress = compress } } func WithMaxSizeSingleFile(maxsize int) SLoggerOption { return func(l *SLogger) { if maxsize < 1 { maxsize = defMaxSize } l.settings.MaxSize = maxsize } } func WithMaxAge(maxage int) SLoggerOption { return func(l *SLogger) { if maxage < 1 { maxage = defMaxAge } l.settings.MaxAge = maxage } } func WithMaxBackups(maxbackups int) SLoggerOption { return func(l *SLogger) { if maxbackups < 1 { maxbackups = defMaxBackups } l.settings.MaxBackups = maxbackups } } /// means log in a single file /// 默认配置: /// json 格式 /// 单文件最大 10 m /// 最多保留1个月 /// 压缩备份 type SLogger struct { f string lg *zap.Logger settings lumberjack.Logger console bool sinks []zap.Sink } // @console: 是否输出到 console // @path: 路径 // @level: 日志等级 // @sinks: 日志额外的输出 func NewSLogger(path string, level string, options ...SLoggerOption) *SLogger { slogger := &SLogger{ f: path, lg: nil, settings: lumberjack.Logger{ Filename: path, MaxSize: defMaxSize, //M MaxAge: defMaxAge, //d MaxBackups: defMaxBackups, //numbers Compress: true, }, console: true, } for _, opt := range options { opt(slogger) } encoderConf := zapcore.EncoderConfig{ MessageKey: "msg", LevelKey: "level", TimeKey: "ts", NameKey: "logger", CallerKey: "caller", StacktraceKey: "trace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } // level corelevel, ok := levelMap[level] if !ok { fmt.Println("Warning: invalid log level: ", level) corelevel = defLevel } atom := zap.NewAtomicLevelAt(corelevel) wss := []zapcore.WriteSyncer{zapcore.AddSync(&slogger.settings)} if slogger.console { wss = append(wss, zapcore.AddSync(os.Stdout)) } for _, sink := range slogger.sinks { wss = append(wss, zapcore.AddSync(sink)) } // writeSyncer ws := zapcore.NewMultiWriteSyncer(wss...) // core core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderConf), ws, atom) caller := zap.AddCaller() callerSkip := zap.AddCallerSkip(2) dev := zap.Development() stack := zap.AddStacktrace(zapcore.ErrorLevel) slogger.lg = zap.New(core, caller, callerSkip, dev, stack) return slogger } func (self *SLogger) Debug(msg string, fields ...zap.Field) { self.lg.Debug(msg, fields...) } func (self *SLogger) Info(msg string, fields ...zap.Field) { self.lg.Info(msg, fields...) } func (self *SLogger) Warn(msg string, fields ...zap.Field) { self.lg.Warn(msg, fields...) } func (self *SLogger) Error(msg string, fields ...zap.Field) { self.lg.Error(msg, fields...) } func (self *SLogger) Panic(msg string, fields ...zap.Field) { self.lg.Panic(msg, fields...) } func (self *SLogger) Fatal(msg string, fields ...zap.Field) { self.lg.Fatal(msg, fields...) } func (self *SLogger) Sync() { _ = self.lg.Sync() } func SetDefaultLogger(logger *SLogger) { defaultLog = logger } func Debug(msg string, fields ...zap.Field) { defaultLog.Debug(msg, fields...) } func Info(msg string, fields ...zap.Field) { defaultLog.Info(msg, fields...) } func Warn(msg string, fields ...zap.Field) { defaultLog.Warn(msg, fields...) } func Error(msg string, fields ...zap.Field) { defaultLog.Error(msg, fields...) } func Panic(msg string, fields ...zap.Field) { defaultLog.Panic(msg, fields...) } func Fatal(msg string, fields ...zap.Field) { defaultLog.Fatal(msg, fields...) } func Sync() { defaultLog.Sync() }