zapGorm2.go 3.0 KB

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