You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
4.7 KiB

  1. package initialize
  2. import (
  3. "context"
  4. "fmt"
  5. "gin-vue-admin/global"
  6. "go.uber.org/zap"
  7. "gorm.io/gorm/logger"
  8. "gorm.io/gorm/utils"
  9. "io/ioutil"
  10. "log"
  11. "os"
  12. "time"
  13. )
  14. var (
  15. Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), GormConfig{})
  16. Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), GormConfig{
  17. SlowThreshold: 200 * time.Millisecond,
  18. LogLevel: logger.Warn,
  19. Colorful: true,
  20. })
  21. Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()}
  22. )
  23. type traceRecorder struct {
  24. logger.Interface
  25. BeginAt time.Time
  26. SQL string
  27. RowsAffected int64
  28. Err error
  29. }
  30. func New(writer Writer, config GormConfig) logger.Interface {
  31. var (
  32. infoStr = "%s\n[info] "
  33. warnStr = "%s\n[warn] "
  34. errStr = "%s\n[error] "
  35. traceStr = "%s\n[%.3fms] [rows:%v] %s"
  36. traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s"
  37. traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s"
  38. )
  39. if config.Colorful {
  40. infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset
  41. warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset
  42. errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset
  43. traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
  44. traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset
  45. traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
  46. }
  47. return &GormLogger{
  48. Writer: writer,
  49. GormConfig: config,
  50. infoStr: infoStr,
  51. warnStr: warnStr,
  52. errStr: errStr,
  53. traceStr: traceStr,
  54. traceWarnStr: traceWarnStr,
  55. traceErrStr: traceErrStr,
  56. }
  57. }
  58. // Writer log writer interface
  59. type Writer interface {
  60. Printf(string, ...interface{})
  61. }
  62. type GormConfig struct {
  63. SlowThreshold time.Duration
  64. Colorful bool
  65. LogLevel logger.LogLevel
  66. }
  67. type GormLogger struct {
  68. Writer
  69. GormConfig
  70. infoStr, warnStr, errStr string
  71. traceStr, traceErrStr, traceWarnStr string
  72. }
  73. func (g *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
  74. newLogger := *g
  75. newLogger.LogLevel = level
  76. return &newLogger
  77. }
  78. func (g *GormLogger) Info(ctx context.Context, message string, data ...interface{}) {
  79. if g.LogLevel >= logger.Info {
  80. g.Printf(g.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  81. }
  82. }
  83. func (g *GormLogger) Warn(ctx context.Context, message string, data ...interface{}) {
  84. if g.LogLevel >= logger.Warn {
  85. g.Printf(g.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  86. }
  87. }
  88. func (g *GormLogger) Error(ctx context.Context, message string, data ...interface{}) {
  89. if g.LogLevel >= logger.Error {
  90. g.Printf(g.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  91. }
  92. }
  93. func (g *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
  94. if g.LogLevel > 0 {
  95. elapsed := time.Since(begin)
  96. switch {
  97. case err != nil && g.LogLevel >= logger.Error:
  98. sql, rows := fc()
  99. if rows == -1 {
  100. g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
  101. } else {
  102. g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
  103. }
  104. case elapsed > g.SlowThreshold && g.SlowThreshold != 0 && g.LogLevel >= logger.Warn:
  105. sql, rows := fc()
  106. slowLog := fmt.Sprintf("SLOW SQL >= %v", g.SlowThreshold)
  107. if rows == -1 {
  108. g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
  109. } else {
  110. g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
  111. }
  112. case g.LogLevel >= logger.Info:
  113. sql, rows := fc()
  114. if rows == -1 {
  115. g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
  116. } else {
  117. g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
  118. }
  119. }
  120. }
  121. }
  122. func (g *GormLogger) Printf(message string, data ...interface{}) {
  123. switch len(data) {
  124. case 0:
  125. global.GVA_LOG.Info(message)
  126. case 1:
  127. global.GVA_LOG.Info("gorm", zap.Any("src", data[0]))
  128. case 2:
  129. global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]))
  130. case 3:
  131. global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]))
  132. case 4:
  133. global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]), zap.Any("sql", data[3]))
  134. }
  135. }