package log import ( "context" "errors" "fmt" "time" "go.uber.org/zap" "gorm.io/gorm/logger" "gorm.io/gorm/utils" ) const ( infoStr = "%s\n[info] " warnStr = "%s\n[warn] " errStr = "%s\n[error] " traceStr = "%s\n[%.3fms] [rows:%v] %s" traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s" traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s" ) func NewGormLogger(sLogger *zap.SugaredLogger) logger.Interface { return &gormLogger{ logger: sLogger, SlowThreshold: 200 * time.Millisecond, LogLevel: logger.Warn, IgnoreRecordNotFoundError: false, infoStr: infoStr, warnStr: warnStr, errStr: errStr, traceStr: traceStr, traceWarnStr: traceWarnStr, traceErrStr: traceErrStr, } } // 数据库默认 type gormLogger struct { logger *zap.SugaredLogger SlowThreshold time.Duration LogLevel logger.LogLevel IgnoreRecordNotFoundError bool infoStr, warnStr, errStr string traceStr, traceErrStr, traceWarnStr string } // LogMode log mode func (l *gormLogger) LogMode(level logger.LogLevel) logger.Interface { newlogger := *l newlogger.LogLevel = level return &newlogger } // Info print info func (l *gormLogger) Info(ctx context.Context, msg string, data ...interface{}) { if l.LogLevel >= logger.Info { l.logf(l.infoStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) } } // Warn print warn messages func (l *gormLogger) Warn(ctx context.Context, msg string, data ...interface{}) { if l.LogLevel >= logger.Warn { l.logf(l.warnStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) } } // Error print error messages func (l *gormLogger) Error(ctx context.Context, msg string, data ...interface{}) { if l.LogLevel >= logger.Error { l.logf(l.errStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) } } // Trace print sql message func (l *gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, 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.logf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.logf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, 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.logf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.logf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) } case l.LogLevel == logger.Info: sql, rows := fc() if rows == -1 { l.logf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.logf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) } } } func (l *gormLogger) logf(format string, data ...interface{}) { l.logger.Logf(l.logger.Level(), format, data...) }