index.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package logx
  2. import (
  3. "go.uber.org/zap"
  4. "go.uber.org/zap/buffer"
  5. "go.uber.org/zap/zapcore"
  6. "gopkg.in/natefinch/lumberjack.v2"
  7. "os"
  8. "path"
  9. "strings"
  10. )
  11. type (
  12. LogConf struct {
  13. Path string // 日志路径
  14. Encoder string // 编码器选择
  15. LogLevel *zapcore.Level // 日志级别
  16. LogFile string // 日志文件路径
  17. MaxSize int // 每个日志文件的最大大小(MB)
  18. MaxBackups int // 保留的旧日志文件个数
  19. RotateDays int // 日志文件的最大保留天数
  20. }
  21. logItem struct {
  22. FileName string
  23. Level zap.LevelEnablerFunc
  24. }
  25. Encoder interface {
  26. Config() zapcore.Encoder
  27. WithKey(key string) Encoder
  28. WithField(key, val string) Encoder
  29. Debug(msg string)
  30. Debugf(format string, v ...interface{})
  31. Info(msg string)
  32. Infof(format string, v ...interface{})
  33. Warn(msg string)
  34. Warnf(format string, v ...interface{})
  35. Error(msg string)
  36. Errorf(format string, v ...interface{})
  37. Fatal(msg string)
  38. Fatalf(format string, v ...interface{})
  39. }
  40. )
  41. var (
  42. maxSize = 200 // 每个日志文件最大尺寸200M
  43. maxBackups = 2 // 日志文件最多保存20个备份
  44. maxAge = 5 // 保留最大天数
  45. logLevel = zapcore.WarnLevel
  46. _logger *zap.Logger
  47. _pool = buffer.NewPool()
  48. ConsoleEncoder = "console" // 控制台输出
  49. JsonEncoder = "json" // json输出
  50. )
  51. // Init 初始化日志.
  52. func Init(conf LogConf) {
  53. if conf.LogLevel == nil {
  54. conf.LogLevel = &logLevel
  55. }
  56. prefix, suffix := getFileSuffixPrefix(conf.Path)
  57. logPath := path.Join(prefix + suffix)
  58. items := []logItem{
  59. {
  60. FileName: logPath,
  61. Level: func(level zapcore.Level) bool {
  62. return level >= *conf.LogLevel
  63. },
  64. },
  65. }
  66. NewLogger(items, conf)
  67. }
  68. // NewLogger 日志.
  69. func NewLogger(items []logItem, conf LogConf) {
  70. var (
  71. cfg zapcore.Encoder
  72. cores []zapcore.Core
  73. )
  74. switch conf.Encoder {
  75. case JsonEncoder:
  76. cfg = NewJsonLog().Config()
  77. case ConsoleEncoder:
  78. cfg = NewConsoleLog().Config()
  79. default:
  80. cfg = NewConsoleLog().Config()
  81. }
  82. if conf.RotateDays == 0 {
  83. conf.RotateDays = maxAge
  84. }
  85. if conf.MaxBackups == 0 {
  86. conf.MaxBackups = maxBackups
  87. }
  88. if conf.MaxSize == 0 {
  89. conf.MaxSize = maxSize
  90. }
  91. for _, v := range items {
  92. hook := lumberjack.Logger{
  93. Filename: v.FileName,
  94. MaxSize: conf.MaxSize, // 每个日志文件保存的最大尺寸 单位:M
  95. MaxBackups: conf.MaxBackups, // 日志文件最多保存多少个备份
  96. MaxAge: conf.RotateDays, // 文件最多保存多少天
  97. Compress: true, // 是否压缩
  98. LocalTime: true, // 备份文件名本地/UTC时间
  99. }
  100. core := zapcore.NewCore(
  101. cfg, // 编码器配置;
  102. zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
  103. v.Level, // 日志级别
  104. )
  105. cores = append(cores, core)
  106. }
  107. // 开启开发模式,堆栈跟踪
  108. caller := zap.AddCaller()
  109. // 开发模式
  110. development := zap.Development()
  111. // 二次封装
  112. skip := zap.AddCallerSkip(1)
  113. // 构造日志
  114. _logger = zap.New(zapcore.NewTee(cores...), caller, development, skip)
  115. return
  116. }
  117. // GetEncoder 获取自定义编码器.
  118. func GetEncoder(conf LogConf) Encoder {
  119. switch conf.Encoder {
  120. case JsonEncoder:
  121. return NewJsonLog()
  122. case ConsoleEncoder:
  123. return NewConsoleLog()
  124. default:
  125. return NewConsoleLog()
  126. }
  127. }
  128. // GetLogger 获取日志记录器.
  129. func GetLogger() *zap.Logger {
  130. return _logger
  131. }
  132. // getFileSuffixPrefix 文件路径切割
  133. func getFileSuffixPrefix(fileName string) (prefix, suffix string) {
  134. paths, _ := path.Split(fileName)
  135. base := path.Base(fileName)
  136. suffix = path.Ext(fileName)
  137. prefix = strings.TrimSuffix(base, suffix)
  138. prefix = path.Join(paths, prefix)
  139. return
  140. }
  141. // getFilePath 自定义获取文件路径.
  142. func getFilePath(ec zapcore.EntryCaller) string {
  143. if !ec.Defined {
  144. return "undefined"
  145. }
  146. buf := _pool.Get()
  147. buf.AppendString(ec.Function)
  148. buf.AppendByte(':')
  149. buf.AppendInt(int64(ec.Line))
  150. caller := buf.String()
  151. buf.Free()
  152. return caller
  153. }