github.com/aaabigfish/gopkg@v1.1.0/log/log.go (about) 1 package log 2 3 import ( 4 "os" 5 "time" 6 7 "github.com/k0kubun/pp/v3" 8 "github.com/mattn/go-isatty" 9 "go.uber.org/zap" 10 "go.uber.org/zap/zapcore" 11 "gopkg.in/natefinch/lumberjack.v2" 12 13 "github.com/aaabigfish/gopkg/config" 14 ) 15 16 var ( 17 _logger *logger 18 ) 19 20 type logger struct { 21 cfg *config.LogConfig 22 sugar *zap.SugaredLogger 23 _level zapcore.Level 24 } 25 26 func initPP() { 27 out := os.Stdout 28 pp.SetDefaultOutput(out) 29 30 if !isatty.IsTerminal(out.Fd()) { 31 pp.ColoringEnabled = false 32 } 33 } 34 35 func init() { 36 initPP() 37 38 _cfg := config.NewLogConfig() 39 40 _logger = &logger{ 41 cfg: _cfg, 42 } 43 lumber := _logger.newLumber() 44 writeSyncer := zapcore.NewMultiWriteSyncer(zapcore.AddSync(lumber)) 45 zapOpt := zap.Fields(zap.String("appname", config.App)) 46 if config.Env != config.EnvProd { 47 zapOpt = zap.Fields(zap.String("appname", config.App), zap.String("env", config.Env)) 48 } 49 50 sugar := zap.New(_logger.newCore(writeSyncer), 51 zap.ErrorOutput(writeSyncer), 52 zap.AddCaller(), 53 zap.AddCallerSkip(1), 54 zapOpt). 55 Sugar() 56 57 _logger.sugar = sugar 58 59 } 60 61 // PP 类似 PHP 的 var_dump 62 func PP(args ...interface{}) { 63 pp.Println(args...) 64 } 65 66 func (l *logger) newCore(ws zapcore.WriteSyncer) zapcore.Core { 67 // 默认日志级别 68 atomicLevel := zap.NewAtomicLevel() 69 defaultLevel := zapcore.DebugLevel 70 // 会解码传递的日志级别,生成新的日志级别 71 _ = (&defaultLevel).UnmarshalText([]byte(l.cfg.Level)) 72 atomicLevel.SetLevel(defaultLevel) 73 l._level = defaultLevel 74 75 // encoder 这部分没有放到配置文件,因为一般配置一次就不会改动 76 encoder := zapcore.EncoderConfig{ 77 MessageKey: "msg", 78 LevelKey: "level", 79 TimeKey: "time", 80 NameKey: "logger", 81 CallerKey: "file", 82 StacktraceKey: "stack", 83 LineEnding: zapcore.DefaultLineEnding, 84 EncodeLevel: zapcore.CapitalColorLevelEncoder, 85 EncodeTime: l.customTimeEncoder, 86 EncodeDuration: zapcore.StringDurationEncoder, 87 EncodeCaller: zapcore.ShortCallerEncoder, 88 EncodeName: zapcore.FullNameEncoder, 89 } 90 var writeSyncer zapcore.WriteSyncer 91 if l.cfg.Console { 92 writeSyncer = zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)) 93 return zapcore.NewCore(zapcore.NewConsoleEncoder(encoder), 94 writeSyncer, 95 atomicLevel) 96 } 97 98 // 输出到文件时,不使用彩色日志,否则会出现乱码 99 encoder.EncodeLevel = zapcore.LowercaseLevelEncoder 100 writeSyncer = ws 101 return zapcore.NewCore(zapcore.NewJSONEncoder(encoder), 102 writeSyncer, 103 atomicLevel) 104 } 105 106 // CustomTimeEncoder 实现了 zapcore.TimeEncoder 107 // 实现对日期格式的自定义转换 108 func (l *logger) customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { 109 format := l.cfg.TimeFormat 110 if len(format) <= 0 { 111 format = "2006-01-02 15:04:05.000" 112 } 113 enc.AppendString(t.Format(format)) 114 } 115 116 func (l *logger) newLumber() *lumberjack.Logger { 117 return &lumberjack.Logger{ 118 Filename: l.cfg.FileName, 119 MaxSize: l.cfg.MaxSize, 120 MaxAge: l.cfg.MaxAge, 121 MaxBackups: l.cfg.MaxBackups, 122 LocalTime: l.cfg.LocalTime, 123 Compress: l.cfg.Compress, 124 } 125 } 126 127 // Fields fields 128 type Field = zap.Field 129 130 func With(key string, val interface{}) *zap.SugaredLogger { 131 return _logger.sugar.With(key, val) 132 } 133 134 func New() *zap.SugaredLogger { 135 return _logger.sugar 136 } 137 138 func Any(key string, val interface{}) Field { 139 return zap.Any(key, val) 140 } 141 142 // Debug 打印debug级别信息 143 func Debug(message string, kvs ...interface{}) { 144 _logger.sugar.Debugw(message, kvs...) 145 } 146 147 // Info 打印info级别信息 148 func Info(message string, kvs ...interface{}) { 149 _logger.sugar.Infow(message, kvs...) 150 } 151 152 // Warn 打印warn级别信息 153 func Warn(message string, kvs ...interface{}) { 154 _logger.sugar.Warnw(message, kvs...) 155 } 156 157 // Error 打印error级别信息 158 func Error(message string, kvs ...interface{}) { 159 _logger.sugar.Errorw(message, kvs...) 160 } 161 162 // Panic 打印错误信息,然后panic 163 func Panic(message string, kvs ...interface{}) { 164 _logger.sugar.Panicw(message, kvs...) 165 } 166 167 // Fatal 打印错误信息,然后退出 168 func Fatal(message string, kvs ...interface{}) { 169 _logger.sugar.Fatalw(message, kvs...) 170 } 171 172 // Debugf 格式化输出debug级别日志 173 func Debugf(template string, args ...interface{}) { 174 _logger.sugar.Debugf(template, args...) 175 } 176 177 // Infof 格式化输出info级别日志 178 func Infof(template string, args ...interface{}) { 179 _logger.sugar.Infof(template, args...) 180 } 181 182 // Warnf 格式化输出warn级别日志 183 func Warnf(template string, args ...interface{}) { 184 _logger.sugar.Warnf(template, args...) 185 } 186 187 // Errorf 格式化输出error级别日志 188 func Errorf(template string, args ...interface{}) { 189 _logger.sugar.Errorf(template, args...) 190 } 191 192 // Panicf 格式化输出日志,并panic 193 func Panicf(template string, args ...interface{}) { 194 _logger.sugar.Panicf(template, args...) 195 } 196 197 // Fatalf 格式化输出日志,并退出 198 func Fatalf(template string, args ...interface{}) { 199 _logger.sugar.Fatalf(template, args...) 200 } 201 202 // Sync 关闭时需要同步日志到输出 203 func Sync() { 204 _ = _logger.sugar.Sync() 205 }