logger.go 3.6 KB

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