1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| package logger
import ( "context" "errors" "go-api-practice/helpers" "go.uber.org/zap" "gorm.io/gorm" gormlogger "gorm.io/gorm/logger" "path/filepath" "runtime" "strings" "time" )
type GormLogger struct { ZapLogger *zap.Logger SlowThreshold time.Duration }
func NewGormLogger() GormLogger { return GormLogger{ ZapLogger: Logger, SlowThreshold: 200 * time.Millisecond, } }
func (l GormLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface { return GormLogger{ ZapLogger: l.ZapLogger, SlowThreshold: l.SlowThreshold, } }
func (l GormLogger) Info(ctx context.Context, str string, args ...interface{}) { l.logger().Sugar().Debugf(str, args...) }
func (l GormLogger) Warn(ctx context.Context, str string, args ...interface{}) { l.logger().Sugar().Warnf(str, args...) }
func (l GormLogger) Error(ctx context.Context, str string, args ...interface{}) { l.logger().Sugar().Errorf(str, args...) }
func (l GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
elapsed := time.Since(begin) sql, rows := fc()
logFields := []zap.Field{ zap.String("sql", sql), zap.String("time", helpers.MicrosecondsStr(elapsed)), zap.Int64("rows", rows), }
if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { l.logger().Warn("Database ErrRecordNotFound", logFields...) } else { logFields = append(logFields, zap.Error(err)) l.logger().Error("Database Error", logFields...) } }
if l.SlowThreshold != 0 && elapsed > l.SlowThreshold { l.logger().Warn("Database Slow Log", logFields...) }
l.logger().Debug("Database Query", logFields...) }
func (l GormLogger) logger() *zap.Logger {
var ( gormPackage = filepath.Join("gorm.io", "gorm") zapgormPackage = filepath.Join("moul.io", "zapgorm2") )
clone := l.ZapLogger.WithOptions(zap.AddCallerSkip(-2))
for i := 2; i < 15; i++ { _, file, _, ok := runtime.Caller(i) switch { case !ok: case strings.HasSuffix(file, "_test.go"): case strings.Contains(file, gormPackage): case strings.Contains(file, zapgormPackage): default: return clone.WithOptions(zap.AddCallerSkip(i)) } } return l.ZapLogger }
|