package gormlog import ( "context" "errors" "fmt" "time" "go.uber.org/zap" "gorm.io/gorm/logger" "gorm.io/gorm/utils" ) type GormLog struct { GormLogParams sug *zap.SugaredLogger } var _ logger.Interface = (*GormLog)(nil) type GormLogParams struct { LogLevel logger.LogLevel SlowThreshold time.Duration IgnoreRecordNotFoundError bool Logger *zap.Logger } func New(params GormLogParams) *GormLog { return &GormLog{ GormLogParams: params, sug: params.Logger.Sugar().Named("gormlog"), } } func (l *GormLog) LogMode(level logger.LogLevel) logger.Interface { var params = l.GormLogParams params.LogLevel = level return New(params) } func (l *GormLog) Info(ctx context.Context, msg string, data ...any) { if l.LogLevel >= logger.Info { l.sug.Info(append([]any{msg}, data...)...) } } func (l *GormLog) Warn(ctx context.Context, msg string, data ...any) { if l.LogLevel >= logger.Warn { l.sug.Warn(append([]any{msg}, data...)...) } } func (l *GormLog) Error(ctx context.Context, msg string, data ...any) { if l.LogLevel >= logger.Error { l.sug.Error(append([]any{msg}, data...)...) } } func (l *GormLog) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { if l.LogLevel <= logger.Silent { return } elapsed := time.Since(begin) switch { case err != nil && l.LogLevel >= logger.Error && (!errors.Is(err, logger.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError): sql, rows := fc() if rows != -1 { l.sug.Errorf("trace %v %v %v %s %s", utils.FileWithLineNum(), err, elapsed.Milliseconds(), "-", sql) } else { l.sug.Errorf("trace %v %v %v %s %s", utils.FileWithLineNum(), err, elapsed.Milliseconds(), rows, sql) } case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn: sql, rows := fc() slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold) if rows == -1 { l.sug.Warnf("trace %v %v %v %s %s", utils.FileWithLineNum(), slowLog, elapsed.Milliseconds(), "-", sql) } else { l.sug.Warnf("trace %v %v %v %s %s", utils.FileWithLineNum(), slowLog, elapsed.Milliseconds(), rows, sql) } case l.LogLevel == logger.Info: sql, rows := fc() if rows != -1 { l.sug.Infof("trace %v %v %s %s", utils.FileWithLineNum(), elapsed.Milliseconds(), "-", sql) } else { l.sug.Infof("trace %v %v %s %s", utils.FileWithLineNum(), elapsed.Milliseconds(), rows, sql) } } }