package logger import ( "context" "errors" "fmt" "log" "path/filepath" "runtime" "time" "gorm.io/gorm/logger" ) type GormLogger struct { LogLevel logger.LogLevel logger *log.Logger } func NewGormLogger() logger.Interface { return &GormLogger{ LogLevel: logger.Info, logger: log.New(DefaultWriter, "", log.LstdFlags|log.Lshortfile), } } func (gl *GormLogger) LogMode(level logger.LogLevel) logger.Interface { newLogger := *gl newLogger.LogLevel = level return &newLogger } func (gl *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) { if gl.LogLevel <= logger.Info { DEBUG(fmt.Sprintf(msg, data...)) } } func (gl *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) { if gl.LogLevel <= logger.Warn { WARN(fmt.Sprintf(msg, data...)) } } func (gl *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) { if gl.LogLevel <= logger.Error { ERROR(fmt.Sprintf(msg, data...), nil) } } func (gl *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { if gl.LogLevel > logger.Silent { elapsed := time.Since(begin) sql, rows := fc() _, file, line, _ := runtime.Caller(3) source := fmt.Sprintf("%s:%d", filepath.Base(file), line) logMsg := struct { Source string Duration string Rows int64 SQL string }{ Source: source, Duration: fmt.Sprintf("%.2f:ms", float64(elapsed.Nanoseconds())/1e6), Rows: rows, SQL: sql, } switch { case err != nil && errors.Is(err, logger.ErrRecordNotFound): ERROR(logMsg, err) case err != nil: ERROR(logMsg, err) default: DEBUG(logMsg) } } }