zapGorm2.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package lxzap
  2. import (
  3. "context"
  4. "errors"
  5. "path/filepath"
  6. "runtime"
  7. "strings"
  8. "time"
  9. "go.uber.org/zap"
  10. "gorm.io/gorm"
  11. gormlogger "gorm.io/gorm/logger"
  12. )
  13. type Logger struct {
  14. ZapLogger *zap.Logger
  15. LogLevel gormlogger.LogLevel
  16. SlowThreshold time.Duration
  17. SkipCallerLookup bool
  18. IgnoreRecordNotFoundError bool
  19. }
  20. func NewGormZap(zapLogger *zap.Logger) Logger {
  21. return Logger{
  22. ZapLogger: zapLogger,
  23. LogLevel: gormlogger.Info,
  24. SlowThreshold: 100 * time.Millisecond,
  25. SkipCallerLookup: false,
  26. IgnoreRecordNotFoundError: false,
  27. }
  28. }
  29. func (l Logger) SetAsDefault() {
  30. gormlogger.Default = l
  31. }
  32. func (l Logger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
  33. return Logger{
  34. ZapLogger: l.ZapLogger,
  35. SlowThreshold: l.SlowThreshold,
  36. LogLevel: level,
  37. SkipCallerLookup: l.SkipCallerLookup,
  38. IgnoreRecordNotFoundError: l.IgnoreRecordNotFoundError,
  39. }
  40. }
  41. func (l Logger) Info(ctx context.Context, str string, args ...interface{}) {
  42. if l.LogLevel < gormlogger.Info {
  43. return
  44. }
  45. l.logger().Sugar().Debugf(str, args...)
  46. }
  47. func (l Logger) Warn(ctx context.Context, str string, args ...interface{}) {
  48. if l.LogLevel < gormlogger.Warn {
  49. return
  50. }
  51. l.logger().Sugar().Warnf(str, args...)
  52. }
  53. func (l Logger) Error(ctx context.Context, str string, args ...interface{}) {
  54. if l.LogLevel < gormlogger.Error {
  55. return
  56. }
  57. l.logger().Sugar().Errorf(str, args...)
  58. }
  59. func (l Logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
  60. spanId := ctx.Value("X-Span-ID")
  61. if l.LogLevel <= 0 {
  62. return
  63. }
  64. elapsed := time.Since(begin)
  65. switch {
  66. case err != nil && l.LogLevel >= gormlogger.Error && (!l.IgnoreRecordNotFoundError || !errors.Is(err, gorm.ErrRecordNotFound)):
  67. sql, rows := fc()
  68. l.logger().Error("trace", zap.Any("spanId", spanId), zap.Error(err), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
  69. case l.SlowThreshold != 0 && elapsed > l.SlowThreshold && l.LogLevel >= gormlogger.Warn:
  70. sql, rows := fc()
  71. l.logger().Warn("trace", zap.Any("spanId", spanId), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
  72. case l.LogLevel >= gormlogger.Info:
  73. sql, rows := fc()
  74. l.logger().Info("trace", zap.Any("spanId", spanId), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows), zap.String("sql", sql))
  75. }
  76. }
  77. var (
  78. gormPackage = filepath.Join("gorm.io", "gorm")
  79. zapgormPackage = filepath.Join("moul.io", "zapgorm2")
  80. )
  81. func (l Logger) logger() *zap.Logger {
  82. for i := 2; i < 15; i++ {
  83. _, file, _, ok := runtime.Caller(i)
  84. file = filepath.Clean(file)
  85. switch {
  86. case !ok:
  87. case strings.HasSuffix(file, "_test.go"):
  88. case strings.Contains(file, gormPackage):
  89. case strings.Contains(file, zapgormPackage):
  90. default:
  91. return l.ZapLogger.WithOptions(zap.AddCallerSkip(i - 1))
  92. }
  93. }
  94. return l.ZapLogger
  95. }