log.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. // log address "out.log" User-defined
  20. lp := conf.GetString("log.log_file_name")
  21. lv := conf.GetString("log.log_level")
  22. var level zapcore.Level
  23. //debug<info<warn<error<fatal<panic
  24. switch lv {
  25. case "debug":
  26. level = zap.DebugLevel
  27. case "info":
  28. level = zap.InfoLevel
  29. case "warn":
  30. level = zap.WarnLevel
  31. case "error":
  32. level = zap.ErrorLevel
  33. default:
  34. level = zap.InfoLevel
  35. }
  36. hook := lumberjack.Logger{
  37. Filename: lp, // Log file path
  38. MaxSize: conf.GetInt("log.max_size"), // Maximum size unit for each log file: M
  39. MaxBackups: conf.GetInt("log.max_backups"), // The maximum number of backups that can be saved for log files
  40. MaxAge: conf.GetInt("log.max_age"), // Maximum number of days the file can be saved
  41. Compress: conf.GetBool("log.compress"), // Compression or not
  42. }
  43. var encoder zapcore.Encoder
  44. if conf.GetString("log.encoding") == "console" {
  45. encoder = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
  46. TimeKey: "ts",
  47. LevelKey: "level",
  48. NameKey: "Logger",
  49. CallerKey: "caller",
  50. MessageKey: "msg",
  51. StacktraceKey: "stacktrace",
  52. LineEnding: zapcore.DefaultLineEnding,
  53. EncodeLevel: zapcore.LowercaseColorLevelEncoder,
  54. EncodeTime: timeEncoder,
  55. EncodeDuration: zapcore.SecondsDurationEncoder,
  56. EncodeCaller: zapcore.FullCallerEncoder,
  57. })
  58. } else {
  59. encoder = zapcore.NewJSONEncoder(zapcore.EncoderConfig{
  60. TimeKey: "ts",
  61. LevelKey: "level",
  62. NameKey: "logger",
  63. CallerKey: "caller",
  64. FunctionKey: zapcore.OmitKey,
  65. MessageKey: "msg",
  66. StacktraceKey: "stacktrace",
  67. LineEnding: zapcore.DefaultLineEnding,
  68. EncodeLevel: zapcore.LowercaseLevelEncoder,
  69. EncodeTime: zapcore.EpochTimeEncoder,
  70. EncodeDuration: zapcore.SecondsDurationEncoder,
  71. EncodeCaller: zapcore.ShortCallerEncoder,
  72. })
  73. }
  74. core := zapcore.NewCore(
  75. encoder,
  76. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // Print to console and file
  77. level,
  78. )
  79. if conf.GetString("env") != "prod" {
  80. return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  81. }
  82. return &Logger{zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
  83. }
  84. func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  85. //enc.AppendString(t.Format("2006-01-02 15:04:05"))
  86. enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
  87. }
  88. // NewContext Adds a field to the specified context
  89. func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) {
  90. ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...))
  91. }
  92. // WithContext Returns a zap instance from the specified context
  93. func (l *Logger) WithContext(ctx *gin.Context) *Logger {
  94. if ctx == nil {
  95. return l
  96. }
  97. zl, _ := ctx.Get(LOGGER_KEY)
  98. ctxLogger, ok := zl.(*zap.Logger)
  99. if ok {
  100. return &Logger{ctxLogger}
  101. }
  102. return l
  103. }