logger.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package logger
  2. import (
  3. "fmt"
  4. "os"
  5. "sync"
  6. "git.listensoft.net/tool/jspkit/config"
  7. "git.listensoft.net/tool/jspkit/logger/zapx"
  8. amqp "github.com/rabbitmq/amqp091-go"
  9. "go.uber.org/zap"
  10. "go.uber.org/zap/zapcore"
  11. "gopkg.in/natefinch/lumberjack.v2"
  12. )
  13. var (
  14. logger *zap.SugaredLogger // 日志对象
  15. mqConn *amqp.Connection // 保存MQ连接
  16. mu sync.Mutex // 用于保护mqConn
  17. )
  18. // InitLogger 初始化日志
  19. func InitLogger(config *config.System) error {
  20. cfg := config.Logger
  21. // 设置默认值
  22. if cfg.MaxSize == 0 {
  23. cfg.MaxSize = 100
  24. }
  25. if cfg.MaxBackups == 0 {
  26. cfg.MaxBackups = 500
  27. }
  28. if cfg.MaxAge == 0 {
  29. cfg.MaxAge = 28
  30. }
  31. // 配置lumberjack
  32. hook := &lumberjack.Logger{
  33. Filename: cfg.Filename,
  34. MaxSize: cfg.MaxSize,
  35. MaxBackups: cfg.MaxBackups,
  36. MaxAge: cfg.MaxAge,
  37. Compress: cfg.Compress,
  38. }
  39. // 设置日志级别
  40. level := zap.InfoLevel
  41. if cfg.Level != "" {
  42. var err error
  43. level, err = zapcore.ParseLevel(cfg.Level)
  44. if err != nil {
  45. return err
  46. }
  47. }
  48. encoderConfig := zapcore.EncoderConfig{
  49. TimeKey: "time",
  50. LevelKey: "level",
  51. NameKey: "logger",
  52. CallerKey: "caller",
  53. MessageKey: "msg",
  54. StacktraceKey: "stacktrace",
  55. LineEnding: zapcore.DefaultLineEnding,
  56. EncodeLevel: zapcore.LowercaseLevelEncoder,
  57. EncodeTime: zapcore.ISO8601TimeEncoder,
  58. EncodeDuration: zapcore.SecondsDurationEncoder,
  59. EncodeCaller: zapcore.ShortCallerEncoder,
  60. }
  61. cores := []zapcore.Core{}
  62. if cfg.ToMq {
  63. dsn := fmt.Sprintf("amqp://%s:%s@%s:%d/", cfg.MqSetting.Username, cfg.MqSetting.Password, cfg.MqSetting.Host, cfg.MqSetting.Port)
  64. conn, err := amqp.Dial(dsn)
  65. if err == nil {
  66. mu.Lock()
  67. mqConn = conn // 保存连接
  68. mu.Unlock()
  69. encoder := zapx.NewEncoder("taxrobot", zapx.CallerTrimmedPath)
  70. wsc, _ := zapx.NewWriter(conn)
  71. cores = append(cores, zapcore.NewCore(encoder, wsc, level))
  72. }
  73. }
  74. // 创建Core
  75. var basecore zapcore.Core
  76. fileWriter := zapcore.AddSync(hook)
  77. if cfg.Console {
  78. // 同时输出到文件和控制台
  79. consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
  80. fileEncoder := zapcore.NewJSONEncoder(encoderConfig)
  81. basecore = zapcore.NewTee(
  82. zapcore.NewCore(fileEncoder, fileWriter, level),
  83. zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), level),
  84. )
  85. } else {
  86. // 只输出到文件
  87. fileEncoder := zapcore.NewJSONEncoder(encoderConfig)
  88. basecore = zapcore.NewCore(fileEncoder, fileWriter, level)
  89. }
  90. cores = append(cores, basecore)
  91. // 创建Logger
  92. logger = zap.New(zapcore.NewTee(cores...), zap.AddCaller(), zap.AddCallerSkip(1)).Sugar()
  93. return nil
  94. }
  95. // GetLogger 获取全局 logger
  96. func GetLogger() *zap.Logger {
  97. // 因为包级别函数的原因,需要调整下 caller skip 后再返回
  98. return logger.Desugar().WithOptions(zap.AddCallerSkip(-1))
  99. }
  100. // 关于为什么用 [Level]ln 系列方法,见 [TestLogVsLogLn]。
  101. // Debug 输出Debug级别日志
  102. func Debug(args ...any) {
  103. logger.Debugln(args...)
  104. }
  105. // Info 输出Info级别日志
  106. func Info(args ...any) {
  107. logger.Infoln(args...)
  108. }
  109. // Warn 输出Warn级别日志
  110. func Warn(args ...any) {
  111. logger.Warnln(args...)
  112. }
  113. // Error 输出Error级别日志
  114. func Error(args ...any) {
  115. logger.Errorln(args...)
  116. }
  117. // Fatal 输出Fatal级别日志
  118. func Fatal(args ...any) {
  119. logger.Fatalln(args...)
  120. }
  121. // Close 关闭日志相关资源,包括MQ连接
  122. func Close() error {
  123. if logger != nil {
  124. logger.Sync()
  125. }
  126. mu.Lock()
  127. defer mu.Unlock()
  128. if mqConn != nil {
  129. err := mqConn.Close()
  130. mqConn = nil
  131. return err
  132. }
  133. return nil
  134. }