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  }