zaplogger.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package log
  2. import (
  3. "fmt"
  4. "os"
  5. "sync"
  6. "time"
  7. "go.uber.org/zap"
  8. "go.uber.org/zap/buffer"
  9. "go.uber.org/zap/zapcore"
  10. "gopkg.in/natefinch/lumberjack.v2"
  11. )
  12. // func InitLogger() {
  13. // writeSyncer := getLogWriter()
  14. // encoder := getEncoder()
  15. // core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
  16. // logger := zap.New(core) //, zap.AddCaller(), zap.AddCallerSkip(1)
  17. // sugarLogger = logger.Sugar()
  18. // }
  19. // var l = new(zapcore.Level)
  20. // err = l.UnmarshalText([]byte(cfg.Level))
  21. // if err != nil {
  22. // return
  23. // }
  24. func InitLogger(appName string, isDisplayConsole bool) (*zap.SugaredLogger, *asyncWriter) {
  25. encoder := getEncoder()
  26. // test.log记录全量日志
  27. filePath1 := fmt.Sprintf("%s.log", appName)
  28. writeSyncer1 := getLogWriter(filePath1, 1024*1024*1024, 7, 7)
  29. // c1 := zapcore.NewCore(encoder, writeSyncer1, zapcore.DebugLevel)
  30. // 异步写入器
  31. entryChan := make(chan *buffer.Buffer, 1000) // 缓冲区大小可以根据实际需求调整
  32. asyncWriter := new(asyncWriter)
  33. asyncWriter.entryChan = entryChan
  34. asyncWriter.writer = writeSyncer1
  35. asyncWriter.pool = buffer.NewPool()
  36. asyncCore := zapcore.NewCore(encoder, zapcore.AddSync(asyncWriter), zapcore.InfoLevel)
  37. asyncWriter.wg.Add(1)
  38. go func() {
  39. defer asyncWriter.wg.Done()
  40. safeWrite := func(entry *buffer.Buffer) {
  41. defer func() {
  42. if err := recover(); err != nil {
  43. fmt.Fprintln(os.Stderr, "panic writing to log file:", err)
  44. }
  45. }()
  46. var err error
  47. if entry.Len() == 0 {
  48. err = writeSyncer1.Sync()
  49. } else {
  50. _, err = writeSyncer1.Write(entry.Bytes())
  51. }
  52. if err != nil {
  53. fmt.Fprintln(os.Stderr, "Error writing to log file:", err)
  54. }
  55. }
  56. for entry := range entryChan {
  57. safeWrite(entry)
  58. entry.Free()
  59. }
  60. }()
  61. // test.err.log记录ERROR级别的日志
  62. filePath2 := fmt.Sprintf("%s.err.log", appName)
  63. writeSyncer2 := getLogWriter(filePath2, 1024*1024*1024, 7, 7)
  64. c2 := zapcore.NewCore(encoder, writeSyncer2, zap.ErrorLevel)
  65. // 使用NewTee将c1和c2合并到core
  66. var core zapcore.Core
  67. if isDisplayConsole {
  68. consoleWriter := zapcore.AddSync(os.Stdout)
  69. c3 := zapcore.NewCore(encoder, consoleWriter, zap.DebugLevel)
  70. core = zapcore.NewTee(asyncCore, c2, c3)
  71. } else {
  72. core = zapcore.NewTee(asyncCore, c2)
  73. }
  74. logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2)) //, zap.AddCaller(), zap.AddCallerSkip(1)
  75. sugarLogger := logger.Sugar()
  76. return sugarLogger, asyncWriter
  77. }
  78. func getEncoder() zapcore.Encoder {
  79. encoderConfig := zap.NewProductionEncoderConfig()
  80. encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(time.DateTime) //ISO8601TimeEncoder //
  81. encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
  82. return zapcore.NewJSONEncoder(encoderConfig)
  83. // NewJSONEncoder
  84. // NewConsoleEncoder
  85. }
  86. // func getLogWriter() zapcore.WriteSyncer {
  87. // file, _ := os.Create("./test.log")
  88. // // 利用io.MultiWriter支持文件和终端两个输出目标
  89. // ws := io.MultiWriter(file, os.Stdout)
  90. // return zapcore.AddSync(ws)
  91. // }
  92. func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer {
  93. lumberJackLogger := &lumberjack.Logger{
  94. Filename: filename,
  95. MaxSize: maxSize,
  96. MaxBackups: maxBackup,
  97. MaxAge: maxAge,
  98. }
  99. return zapcore.AddSync(lumberJackLogger)
  100. }
  101. // 异步写入器
  102. type asyncWriter struct {
  103. entryChan chan *buffer.Buffer
  104. wg sync.WaitGroup
  105. writer zapcore.WriteSyncer
  106. pool buffer.Pool
  107. }
  108. func (w *asyncWriter) Write(p []byte) (n int, err error) {
  109. buffer := w.pool.Get()
  110. buffer.Write(p)
  111. w.entryChan <- buffer
  112. return len(p), nil
  113. }
  114. func (w *asyncWriter) Sync() error {
  115. buffer := w.pool.Get()
  116. w.entryChan <- buffer
  117. return nil
  118. // return w.writer.Sync()
  119. }
  120. func testzaplog() {
  121. log, w := InitLogger("test", false)
  122. defer func() {
  123. log.Sync()
  124. close(w.entryChan)
  125. w.wg.Wait()
  126. }()
  127. log.Info("info")
  128. log.Error("error")
  129. log.Debug("debug")
  130. log.Warn("warn")
  131. // log.Panic("panic")
  132. log.Fatal("fatal")
  133. // time.Sleep(time.Second * 1000)
  134. // defer sugarLogger.Sync()
  135. }