gorm.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package logger
  2. import (
  3. "context"
  4. "errors"
  5. "log/slog"
  6. "regexp"
  7. "strings"
  8. "time"
  9. )
  10. import (
  11. "gorm.io/gorm"
  12. gormlogger "gorm.io/gorm/logger"
  13. )
  14. var (
  15. pbkdf2Re *regexp.Regexp
  16. )
  17. func init() {
  18. pbkdf2Re, _ = regexp.Compile(`'pbkdf2:\S+?'`)
  19. }
  20. func desensitize(str string) string {
  21. fs := pbkdf2Re.FindAllString(str, -1)
  22. if len(fs) > 0 {
  23. for _, f := range fs {
  24. str = strings.Replace(str, f, "'******'", -1)
  25. }
  26. }
  27. return str
  28. }
  29. type GormLogger struct {
  30. Logger *slog.Logger
  31. LogLevel gormlogger.LogLevel
  32. SlowThreshold time.Duration
  33. SkipCallerLookup bool
  34. IgnoreRecordNotFoundError bool
  35. }
  36. func NewGormLogger(logger2 *slog.Logger) *GormLogger {
  37. return &GormLogger{
  38. Logger: logger2,
  39. LogLevel: gormlogger.Info,
  40. SlowThreshold: 100 * time.Millisecond,
  41. SkipCallerLookup: false,
  42. IgnoreRecordNotFoundError: true,
  43. }
  44. }
  45. func (l GormLogger) SetAsDefault() {
  46. gormlogger.Default = l
  47. }
  48. func (l GormLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
  49. return GormLogger{
  50. SlowThreshold: l.SlowThreshold,
  51. LogLevel: level,
  52. SkipCallerLookup: l.SkipCallerLookup,
  53. IgnoreRecordNotFoundError: l.IgnoreRecordNotFoundError,
  54. }
  55. }
  56. func (l GormLogger) Info(ctx context.Context, str string, args ...interface{}) {
  57. if l.LogLevel < gormlogger.Info {
  58. return
  59. }
  60. logger.Info(str, slog.Any("data", args))
  61. }
  62. func (l GormLogger) Warn(ctx context.Context, str string, args ...interface{}) {
  63. if l.LogLevel < gormlogger.Warn {
  64. return
  65. }
  66. logger.Warn(str, slog.Any("data", args))
  67. }
  68. func (l GormLogger) Error(ctx context.Context, str string, args ...interface{}) {
  69. if l.LogLevel < gormlogger.Error {
  70. return
  71. }
  72. logger.Error(str, slog.Any("data", args))
  73. }
  74. func (l GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
  75. if l.LogLevel <= 0 {
  76. return
  77. }
  78. elapsed := time.Since(begin)
  79. switch {
  80. case err != nil && l.LogLevel >= gormlogger.Error && (!l.IgnoreRecordNotFoundError || !errors.Is(err, gorm.ErrRecordNotFound)):
  81. sql, rows := fc()
  82. logger.Error("gorm trace error", "err", err, "elapsed", elapsed, "rows", rows, "sql", desensitize(sql))
  83. case l.SlowThreshold != 0 && elapsed > l.SlowThreshold && l.LogLevel >= gormlogger.Warn:
  84. sql, rows := fc()
  85. logger.Warn("gorm trace warn", "elapsed", elapsed, "rows", rows, "sql", desensitize(sql))
  86. case l.LogLevel >= gormlogger.Info:
  87. sql, rows := fc()
  88. logger.Info("gorm trace info", "elapsed", elapsed, "rows", rows, "sql", desensitize(sql))
  89. }
  90. }