log.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package log
  2. import (
  3. "io"
  4. "os"
  5. "go.uber.org/zap"
  6. "go.uber.org/zap/zapcore"
  7. "gopkg.in/natefinch/lumberjack.v2"
  8. )
  9. var (
  10. _logger *zap.Logger
  11. )
  12. const (
  13. // FormatText format log text
  14. FormatText = "text"
  15. // FormatJSON format log json
  16. FormatJSON = "json"
  17. )
  18. // type Level uint
  19. // 日志配置
  20. type logConfig struct {
  21. LogPath string
  22. LogLevel string
  23. Compress bool
  24. MaxSize int
  25. MaxAge int
  26. MaxBackups int
  27. Format string
  28. }
  29. func getzapLevel(level string) zapcore.Level {
  30. switch level {
  31. case "debug":
  32. return zap.DebugLevel
  33. case "info":
  34. return zap.InfoLevel
  35. case "warn":
  36. return zap.WarnLevel
  37. case "error":
  38. return zap.ErrorLevel
  39. case "panic":
  40. return zap.PanicLevel
  41. case "fatal":
  42. return zap.FatalLevel
  43. default:
  44. return zap.InfoLevel
  45. }
  46. }
  47. func newLogWriter(logpath string, maxsize, maxAge, maxBackups int, compress bool) io.Writer {
  48. if logpath == "" || logpath == "-" {
  49. return os.Stdout
  50. }
  51. return &lumberjack.Logger{
  52. Filename: logpath,
  53. MaxSize: maxsize,
  54. Compress: compress,
  55. MaxAge: maxAge, // 保留天数
  56. MaxBackups: maxBackups, // 最多保留的备份数
  57. }
  58. }
  59. func newZapEncoder() zapcore.EncoderConfig {
  60. encoderConfig := zapcore.EncoderConfig{
  61. TimeKey: "time",
  62. LevelKey: "level",
  63. NameKey: "logger",
  64. CallerKey: "line",
  65. MessageKey: "msg",
  66. StacktraceKey: "stacktrace",
  67. LineEnding: zapcore.DefaultLineEnding,
  68. EncodeLevel: zapcore.LowercaseLevelEncoder, // 小写编码器
  69. EncodeTime: zapcore.ISO8601TimeEncoder, // ISO8601 UTC 时间格式
  70. EncodeDuration: zapcore.SecondsDurationEncoder, //
  71. EncodeCaller: zapcore.ShortCallerEncoder, // 全路径编码器
  72. EncodeName: zapcore.FullNameEncoder,
  73. }
  74. return encoderConfig
  75. }
  76. func newLoggerCore(log *logConfig) zapcore.Core {
  77. hook := newLogWriter(log.LogPath, log.MaxSize, log.MaxAge, log.MaxBackups, log.Compress)
  78. encoderConfig := newZapEncoder()
  79. atomLevel := zap.NewAtomicLevelAt(getzapLevel(log.LogLevel))
  80. var encoder zapcore.Encoder
  81. if log.Format == FormatJSON {
  82. encoder = zapcore.NewJSONEncoder(encoderConfig)
  83. } else {
  84. encoder = zapcore.NewConsoleEncoder(encoderConfig)
  85. }
  86. core := zapcore.NewCore(
  87. encoder,
  88. zapcore.NewMultiWriteSyncer(zapcore.AddSync(hook)),
  89. atomLevel,
  90. )
  91. return core
  92. }
  93. func newLoggerOptions() []zap.Option {
  94. // 开启开发模式,堆栈跟踪
  95. caller := zap.AddCaller()
  96. callerskip := zap.AddCallerSkip(1)
  97. // 开发者
  98. development := zap.Development()
  99. options := []zap.Option{
  100. caller,
  101. callerskip,
  102. development,
  103. }
  104. return options
  105. }
  106. // Option function option
  107. type Option func(*logConfig)
  108. // Path set logpath
  109. // if is zero will print,or write file
  110. func Path(logpath string) Option {
  111. return func(logcfg *logConfig) {
  112. logcfg.LogPath = logpath
  113. }
  114. }
  115. // Compress compress log
  116. func Compress(compress bool) Option {
  117. return func(logcfg *logConfig) {
  118. logcfg.Compress = compress
  119. }
  120. }
  121. // Level set log level default info
  122. func Level(level string) Option {
  123. return func(logcfg *logConfig) {
  124. logcfg.LogLevel = level
  125. }
  126. }
  127. // MaxSize Log Max Size
  128. func MaxSize(size int) Option {
  129. return func(logcfg *logConfig) {
  130. logcfg.MaxSize = size
  131. }
  132. }
  133. // MaxAge log store day
  134. func MaxAge(age int) Option {
  135. return func(logcfg *logConfig) {
  136. logcfg.MaxAge = age
  137. }
  138. }
  139. // MaxBackups total store log
  140. func MaxBackups(backup int) Option {
  141. return func(logcfg *logConfig) {
  142. logcfg.MaxBackups = backup
  143. }
  144. }
  145. // Format log json or text
  146. func Format(format string) Option {
  147. return func(logcfg *logConfig) {
  148. if format == FormatJSON {
  149. logcfg.Format = FormatJSON
  150. } else {
  151. logcfg.Format = FormatText
  152. }
  153. }
  154. }
  155. func defaultOption() *logConfig {
  156. return &logConfig{
  157. LogPath: "",
  158. MaxSize: 20,
  159. Compress: true,
  160. MaxAge: 7,
  161. MaxBackups: 7,
  162. LogLevel: "debug",
  163. Format: FormatText,
  164. }
  165. }
  166. // InitLog conf
  167. func InitLog(opts ...Option) error {
  168. logcfg := defaultOption()
  169. for _, opt := range opts {
  170. opt(logcfg)
  171. }
  172. core := newLoggerCore(logcfg)
  173. zapopts := newLoggerOptions()
  174. _logger = zap.New(core, zapopts...)
  175. return nil
  176. }
  177. // Debug output log
  178. func Debug(msg string, fields ...zap.Field) {
  179. _logger.Debug(msg, fields...)
  180. }
  181. // Info output log
  182. func Info(msg string, fields ...zap.Field) {
  183. _logger.Info(msg, fields...)
  184. }
  185. // Warn output log
  186. func Warn(msg string, fields ...zap.Field) {
  187. _logger.Warn(msg, fields...)
  188. }
  189. // Error output log
  190. func Error(msg string, fields ...zap.Field) {
  191. _logger.Error(msg, fields...)
  192. }
  193. // Panic output panic
  194. func Panic(msg string, fields ...zap.Field) {
  195. _logger.Panic(msg, fields...)
  196. }
  197. // Fatal output log
  198. func Fatal(msg string, fields ...zap.Field) {
  199. _logger.Fatal(msg, fields...)
  200. }