log.go 4.4 KB

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