log.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. // 日志地址 "out.log" 自定义
  17. lp := conf.GetString("log.log_file_name")
  18. // 日志级别 DEBUG,ERROR, INFO
  19. lv := conf.GetString("log.log_level")
  20. var level zapcore.Level
  21. //debug<info<warn<error<fatal<panic
  22. switch lv {
  23. case "debug":
  24. level = zap.DebugLevel
  25. case "info":
  26. level = zap.InfoLevel
  27. case "warn":
  28. level = zap.WarnLevel
  29. case "error":
  30. level = zap.ErrorLevel
  31. default:
  32. level = zap.InfoLevel
  33. }
  34. hook := lumberjack.Logger{
  35. Filename: lp, // 日志文件路径
  36. MaxSize: conf.GetInt("log.max_size"), // 每个日志文件保存的最大尺寸 单位:M
  37. MaxBackups: conf.GetInt("log.max_backups"), // 日志文件最多保存多少个备份
  38. MaxAge: conf.GetInt("log.max_age"), // 文件最多保存多少天
  39. Compress: conf.GetBool("log.compress"), // 是否压缩
  40. }
  41. // 是否 DEBUG
  42. if conf.GetString("env") != "prod" {
  43. core := zapcore.NewCore(
  44. zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
  45. TimeKey: "ts",
  46. LevelKey: "level",
  47. NameKey: "Logger",
  48. CallerKey: "caller",
  49. MessageKey: "msg",
  50. StacktraceKey: "stacktrace",
  51. LineEnding: zapcore.DefaultLineEnding,
  52. EncodeLevel: zapcore.LowercaseColorLevelEncoder,
  53. EncodeTime: timeEncoder,
  54. EncodeDuration: zapcore.SecondsDurationEncoder,
  55. EncodeCaller: zapcore.FullCallerEncoder,
  56. }), // 编码器配置
  57. //zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), // 打印到控制台
  58. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  59. level, // 日志级别
  60. )
  61. // 开启开发模式,堆栈跟踪
  62. caller := zap.AddCaller()
  63. // 开启文件及行号
  64. development := zap.Development()
  65. // 设置初始化字段
  66. //filed := zap.Fields(zap.String("serviceName", "serviceName"))
  67. // 构造日志
  68. return &Logger{zap.New(core, caller, development, zap.AddStacktrace(zap.ErrorLevel))}
  69. } else {
  70. encoderConfig := zap.NewProductionEncoderConfig()
  71. return &Logger{zap.New(zapcore.NewCore(
  72. zapcore.NewJSONEncoder(encoderConfig), // 编码器配置(生产环境使用json)
  73. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  74. level, // 日志级别
  75. ), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  76. }
  77. }
  78. // 自定义时间编码器
  79. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  80. enc.AppendString(t.Format("2006-01-02 15:04:05"))
  81. //enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
  82. }
  83. // NewGinContext 给指定的context添加字段
  84. func (l *Logger) NewGinContext(ctx *gin.Context, fields ...zapcore.Field) {
  85. ctx.Set(LOGGER_KEY, l.WithGinContext(ctx).With(fields...))
  86. }
  87. // WithGinContext 从指定的context返回一个zap实例
  88. func (l *Logger) WithGinContext(ctx *gin.Context) *Logger {
  89. if ctx == nil {
  90. return l
  91. }
  92. zl, _ := ctx.Get(LOGGER_KEY)
  93. ctxLogger, ok := zl.(*zap.Logger)
  94. if ok {
  95. return &Logger{ctxLogger}
  96. }
  97. return l
  98. }