log.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package log
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/spf13/viper"
  5. "go.uber.org/zap"
  6. "go.uber.org/zap/zapcore"
  7. "gopkg.in/natefinch/lumberjack.v2"
  8. "os"
  9. "time"
  10. )
  11. const LOGGER_KEY = "zapLogger"
  12. type Logger struct {
  13. *zap.Logger
  14. }
  15. func NewLog(conf *viper.Viper) *Logger {
  16. return initZap(conf)
  17. }
  18. func initZap(conf *viper.Viper) *Logger {
  19. // 日志地址 "out.log" 自定义
  20. lp := conf.GetString("log.log_file_name")
  21. // 日志级别 DEBUG,ERROR, INFO
  22. lv := conf.GetString("log.log_level")
  23. var level zapcore.Level
  24. //debug<info<warn<error<fatal<panic
  25. switch lv {
  26. case "debug":
  27. level = zap.DebugLevel
  28. case "info":
  29. level = zap.InfoLevel
  30. case "warn":
  31. level = zap.WarnLevel
  32. case "error":
  33. level = zap.ErrorLevel
  34. default:
  35. level = zap.InfoLevel
  36. }
  37. hook := lumberjack.Logger{
  38. Filename: lp, // 日志文件路径
  39. MaxSize: conf.GetInt("log.max_size"), // 每个日志文件保存的最大尺寸 单位:M
  40. MaxBackups: conf.GetInt("log.max_backups"), // 日志文件最多保存多少个备份
  41. MaxAge: conf.GetInt("log.max_age"), // 文件最多保存多少天
  42. Compress: conf.GetBool("log.compress"), // 是否压缩
  43. }
  44. var encoder zapcore.Encoder
  45. if conf.GetString("log.encoding") == "console" {
  46. encoder = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
  47. TimeKey: "ts",
  48. LevelKey: "level",
  49. NameKey: "Logger",
  50. CallerKey: "caller",
  51. MessageKey: "msg",
  52. StacktraceKey: "stacktrace",
  53. LineEnding: zapcore.DefaultLineEnding,
  54. EncodeLevel: zapcore.LowercaseColorLevelEncoder,
  55. EncodeTime: timeEncoder,
  56. EncodeDuration: zapcore.SecondsDurationEncoder,
  57. EncodeCaller: zapcore.FullCallerEncoder,
  58. })
  59. } else {
  60. encoder = zapcore.NewJSONEncoder(zapcore.EncoderConfig{
  61. TimeKey: "ts",
  62. LevelKey: "level",
  63. NameKey: "logger",
  64. CallerKey: "caller",
  65. FunctionKey: zapcore.OmitKey,
  66. MessageKey: "msg",
  67. StacktraceKey: "stacktrace",
  68. LineEnding: zapcore.DefaultLineEnding,
  69. EncodeLevel: zapcore.LowercaseLevelEncoder,
  70. EncodeTime: zapcore.EpochTimeEncoder,
  71. EncodeDuration: zapcore.SecondsDurationEncoder,
  72. EncodeCaller: zapcore.ShortCallerEncoder,
  73. })
  74. }
  75. core := zapcore.NewCore(
  76. encoder, // 编码器配置
  77. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  78. level, // 日志级别
  79. )
  80. if conf.GetString("env") != "prod" {
  81. return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  82. }
  83. return &Logger{zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  84. }
  85. // 自定义时间编码器
  86. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  87. //enc.AppendString(t.Format("2006-01-02 15:04:05"))
  88. enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
  89. }
  90. // NewContext 给指定的context添加字段
  91. func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) {
  92. ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...))
  93. }
  94. // WithContext 从指定的context返回一个zap实例
  95. func (l *Logger) WithContext(ctx *gin.Context) *Logger {
  96. if ctx == nil {
  97. return l
  98. }
  99. zl, _ := ctx.Get(LOGGER_KEY)
  100. ctxLogger, ok := zl.(*zap.Logger)
  101. if ok {
  102. return &Logger{ctxLogger}
  103. }
  104. return l
  105. }