log.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. // 是否 DEBUG
  45. if conf.GetString("env") != "prod" {
  46. core := zapcore.NewCore(
  47. zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
  48. TimeKey: "ts",
  49. LevelKey: "level",
  50. NameKey: "Logger",
  51. CallerKey: "caller",
  52. MessageKey: "msg",
  53. StacktraceKey: "stacktrace",
  54. LineEnding: zapcore.DefaultLineEnding,
  55. EncodeLevel: zapcore.LowercaseColorLevelEncoder,
  56. EncodeTime: timeEncoder,
  57. EncodeDuration: zapcore.SecondsDurationEncoder,
  58. EncodeCaller: zapcore.FullCallerEncoder,
  59. }), // 编码器配置
  60. //zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), // 打印到控制台
  61. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  62. level, // 日志级别
  63. )
  64. // 开启开发模式,堆栈跟踪
  65. caller := zap.AddCaller()
  66. // 开启文件及行号
  67. development := zap.Development()
  68. // 设置初始化字段
  69. //filed := zap.Fields(zap.String("serviceName", "serviceName"))
  70. // 构造日志
  71. return &Logger{zap.New(core, caller, development, zap.AddStacktrace(zap.ErrorLevel))}
  72. } else {
  73. encoderConfig := zap.NewProductionEncoderConfig()
  74. return &Logger{zap.New(zapcore.NewCore(
  75. zapcore.NewJSONEncoder(encoderConfig), // 编码器配置(生产环境使用json)
  76. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  77. level, // 日志级别
  78. ), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  79. }
  80. }
  81. // 自定义时间编码器
  82. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  83. enc.AppendString(t.Format("2006-01-02 15:04:05"))
  84. //enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
  85. }
  86. // NewContext 给指定的context添加字段
  87. func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) {
  88. ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...))
  89. }
  90. // WithContext 从指定的context返回一个zap实例
  91. func (l *Logger) WithContext(ctx *gin.Context) *Logger {
  92. if ctx == nil {
  93. return l
  94. }
  95. zl, _ := ctx.Get(LOGGER_KEY)
  96. ctxLogger, ok := zl.(*zap.Logger)
  97. if ok {
  98. return &Logger{ctxLogger}
  99. }
  100. return l
  101. }