package gormlogrus import ( "context" "errors" "fmt" "time" "github.com/sirupsen/logrus" "gorm.io/gorm" gormlogger "gorm.io/gorm/logger" "gorm.io/gorm/utils" ) type GormLogrusAdapter struct { SlowThreshold time.Duration SourceField string SkipErrRecordNotFound bool Logger logrus.FieldLogger } func New(logger logrus.FieldLogger) *GormLogrusAdapter { return &GormLogrusAdapter{ Logger: logger, SkipErrRecordNotFound: false, SourceField: "gorm", SlowThreshold: 1 * time.Second, } } func (l *GormLogrusAdapter) LogMode(gormlogger.LogLevel) gormlogger.Interface { return l } func (l *GormLogrusAdapter) Info(ctx context.Context, s string, args ...interface{}) { l.Logger.Infof(s, args) } func (l *GormLogrusAdapter) Warn(ctx context.Context, s string, args ...interface{}) { logrus.Warnf(s, args) } func (l *GormLogrusAdapter) Error(ctx context.Context, s string, args ...interface{}) { logrus.Errorf(s, args) } func (l *GormLogrusAdapter) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { elapsed := time.Since(begin) sql, rowsAffectedNum := fc() fields := logrus.Fields{} if l.SourceField != "" { fields[l.SourceField] = utils.FileWithLineNum() } // format := "%s [cost: %s] [rows: %d]" // args := []interface{}{sql, elapsed, rowsAffectedNum} msg := fmt.Sprintf("%s [cost: %s] [rows: %d]", sql, elapsed, rowsAffectedNum) if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.SkipErrRecordNotFound) { fields[logrus.ErrorKey] = err l.Logger.WithFields(fields).Error(msg) return } if l.SlowThreshold != 0 && elapsed > l.SlowThreshold { l.Logger.WithFields(fields).Warn(msg) return } l.Logger.WithFields(fields).Debug(msg) }