package db import ( "admin/lib/xlog" "context" "fmt" "gorm.io/gorm/logger" "strings" "time" ) type gormLogger struct { } func (l *gormLogger) LogMode(logger.LogLevel) logger.Interface { return l } func (l *gormLogger) Info(ctx context.Context, format string, args ...interface{}) { xlog.Infof(fmt.Sprintf("[GORM LOGGER] "+format, args...)) } func (l *gormLogger) Warn(ctx context.Context, format string, args ...interface{}) { xlog.Warnf(fmt.Sprintf("[GORM LOGGER] "+format, args...)) } func (l *gormLogger) Error(ctx context.Context, format string, args ...interface{}) { xlog.Errorf(fmt.Sprintf("[GORM LOGGER] "+format, args...)) } func (l *gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { sqlStr, aff := fc() if strings.Contains(sqlStr, "SHOW STATUS") { return } if err != nil { xlog.Errorf("[GORM LOGGER] "+"sql:%v affected:%v error:%v", sqlStr, aff, err) cmd, table := getSqlCmdAndTable(sqlStr) if cmd == "" || table == "" { return } //metricsMysqlErrorCount.LabelValues(cmd, table).Add(1) } else { dura := time.Now().Sub(begin) if dura.Milliseconds() > 2000 { xlog.Warnf("[GORM LOGGER] [SLOW] "+"sql:%v affected:%v use %vms", sqlStr, aff, dura.Milliseconds()) } else { xlog.Tracef("[GORM LOGGER] "+"sql:%v affected:%v", sqlStr, aff) } } } func getSqlCmdAndTable(sql string) (string, string) { cmd := "" table := "" idx := strings.IndexAny(sql, " ") if idx <= 0 { cmd = sql } else { cmd = sql[:idx] } switch cmd { case "SELECT": if idx := strings.Index(sql, "FROM"); idx >= 0 { for i := idx + 5; i < len(sql); i++ { if sql[i] == ' ' { break } table += string(sql[i]) } } case "UPDATE": if idx := strings.Index(sql, "UPDATE"); idx >= 0 { for i := idx + 7; i < len(sql); i++ { if sql[i] == ' ' { break } table += string(sql[i]) } } case "INSERT": if idx := strings.Index(sql, "INTO"); idx >= 0 { for i := idx + 5; i < len(sql); i++ { if sql[i] == ' ' || sql[i] == '(' { break } table += string(sql[i]) } } case "DELETE": if idx := strings.Index(sql, "FROM"); idx >= 0 { for i := idx + 5; i < len(sql); i++ { if sql[i] == ' ' { break } table += string(sql[i]) } } default: } return cmd, table }