log.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package log
  2. import (
  3. "go.uber.org/zap"
  4. "go.uber.org/zap/zapcore"
  5. "gopkg.in/natefinch/lumberjack.v2"
  6. "io"
  7. "os"
  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, maxbacks 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. MaxBackups: maxbacks,
  55. Compress: compress,
  56. }
  57. }
  58. func newZapEncoder() zapcore.EncoderConfig {
  59. encoderConfig := zapcore.EncoderConfig{
  60. TimeKey: "time",
  61. LevelKey: "level",
  62. NameKey: "logger",
  63. CallerKey: "line",
  64. MessageKey: "msg",
  65. StacktraceKey: "stacktrace",
  66. LineEnding: zapcore.DefaultLineEnding,
  67. EncodeLevel: zapcore.LowercaseLevelEncoder, // 小写编码器
  68. EncodeTime: zapcore.ISO8601TimeEncoder, // ISO8601 UTC 时间格式
  69. EncodeDuration: zapcore.SecondsDurationEncoder, //
  70. EncodeCaller: zapcore.ShortCallerEncoder, // 全路径编码器
  71. EncodeName: zapcore.FullNameEncoder,
  72. }
  73. return encoderConfig
  74. }
  75. func newLoggerCore(log *logConfig) zapcore.Core {
  76. hook := newLogWriter(log.LogPath, log.MaxSize, log.MaxBackups, log.Compress)
  77. encoderConfig := newZapEncoder()
  78. atomLevel := zap.NewAtomicLevelAt(getzapLevel(log.LogLevel))
  79. var encoder zapcore.Encoder
  80. if log.Format == FormatJSON {
  81. encoder = zapcore.NewJSONEncoder(encoderConfig)
  82. } else {
  83. encoder = zapcore.NewConsoleEncoder(encoderConfig)
  84. }
  85. core := zapcore.NewCore(
  86. encoder,
  87. zapcore.NewMultiWriteSyncer(zapcore.AddSync(hook)),
  88. atomLevel,
  89. )
  90. return core
  91. }
  92. func newLoggerOptions() []zap.Option {
  93. // 开启开发模式,堆栈跟踪
  94. caller := zap.AddCaller()
  95. callerskip := zap.AddCallerSkip(1)
  96. // 开发者
  97. development := zap.Development()
  98. options := []zap.Option{
  99. caller,
  100. callerskip,
  101. development,
  102. }
  103. return options
  104. }
  105. // Option function option
  106. type Option func(*logConfig)
  107. // Path set logpath
  108. // if is zero will print,or write file
  109. func Path(logpath string) Option {
  110. return func(logcfg *logConfig) {
  111. logcfg.LogPath = logpath
  112. }
  113. }
  114. // Compress compress log
  115. func Compress(compress bool) Option {
  116. return func(logcfg *logConfig) {
  117. logcfg.Compress = compress
  118. }
  119. }
  120. // Level set log level default info
  121. func Level(level string) Option {
  122. return func(logcfg *logConfig) {
  123. logcfg.LogLevel = level
  124. }
  125. }
  126. // MaxSize Log Max Size
  127. func MaxSize(size int) Option {
  128. return func(logcfg *logConfig) {
  129. logcfg.MaxSize = size
  130. }
  131. }
  132. // MaxAge log store day
  133. func MaxAge(age int) Option {
  134. return func(logcfg *logConfig) {
  135. logcfg.MaxAge = age
  136. }
  137. }
  138. // MaxBackups total store log
  139. func MaxBackups(backup int) Option {
  140. return func(logcfg *logConfig) {
  141. logcfg.MaxBackups = backup
  142. }
  143. }
  144. // Format log json or text
  145. func Format(format string) Option {
  146. return func(logcfg *logConfig) {
  147. if format == FormatJSON {
  148. logcfg.Format = FormatJSON
  149. } else {
  150. logcfg.Format = FormatText
  151. }
  152. }
  153. }
  154. func defaultOption() *logConfig {
  155. return &logConfig{
  156. LogPath: "",
  157. MaxSize: 20,
  158. Compress: true,
  159. MaxAge: 7,
  160. MaxBackups: 7,
  161. LogLevel: "debug",
  162. Format: FormatText,
  163. }
  164. }
  165. // InitLog conf
  166. func InitLog(opts ...Option) error {
  167. logcfg := defaultOption()
  168. for _, opt := range opts {
  169. opt(logcfg)
  170. }
  171. core := newLoggerCore(logcfg)
  172. zapopts := newLoggerOptions()
  173. _logger = zap.New(core, zapopts...)
  174. return nil
  175. }
  176. // Debug output log
  177. func Debug(msg string, fields ...zap.Field) {
  178. _logger.Debug(msg, fields...)
  179. }
  180. // Info output log
  181. func Info(msg string, fields ...zap.Field) {
  182. _logger.Info(msg, fields...)
  183. }
  184. // Warn output log
  185. func Warn(msg string, fields ...zap.Field) {
  186. _logger.Warn(msg, fields...)
  187. }
  188. // Error output log
  189. func Error(msg string, fields ...zap.Field) {
  190. _logger.Error(msg, fields...)
  191. }
  192. // Panic output panic
  193. func Panic(msg string, fields ...zap.Field) {
  194. _logger.Panic(msg, fields...)
  195. }
  196. // Fatal output log
  197. func Fatal(msg string, fields ...zap.Field) {
  198. _logger.Fatal(msg, fields...)
  199. }