Browse Source

support log db

liuzhifei 1 year ago
parent
commit
d82bd20354
2 changed files with 129 additions and 60 deletions
  1. 13 13
      model/log.go
  2. 116 47
      model/main.go

+ 13 - 13
model/log.go

@@ -38,7 +38,7 @@ const (
 )
 
 func GetLogByKey(key string) (logs []*Log, err error) {
-	err = DB.Joins("left join tokens on tokens.id = logs.token_id").Where("tokens.key = ?", strings.TrimPrefix(key, "sk-")).Find(&logs).Error
+	err = LOG_DB.Joins("left join tokens on tokens.id = logs.token_id").Where("tokens.key = ?", strings.TrimPrefix(key, "sk-")).Find(&logs).Error
 	return logs, err
 }
 
@@ -54,7 +54,7 @@ func RecordLog(userId int, logType int, content string) {
 		Type:      logType,
 		Content:   content,
 	}
-	err := DB.Create(log).Error
+	err := LOG_DB.Create(log).Error
 	if err != nil {
 		common.SysError("failed to record log: " + err.Error())
 	}
@@ -84,7 +84,7 @@ func RecordConsumeLog(ctx context.Context, userId int, channelId int, promptToke
 		IsStream:         isStream,
 		Other:            otherStr,
 	}
-	err := DB.Create(log).Error
+	err := LOG_DB.Create(log).Error
 	if err != nil {
 		common.LogError(ctx, "failed to record log: "+err.Error())
 	}
@@ -98,9 +98,9 @@ func RecordConsumeLog(ctx context.Context, userId int, channelId int, promptToke
 func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, startIdx int, num int, channel int) (logs []*Log, err error) {
 	var tx *gorm.DB
 	if logType == LogTypeUnknown {
-		tx = DB
+		tx = LOG_DB
 	} else {
-		tx = DB.Where("type = ?", logType)
+		tx = LOG_DB.Where("type = ?", logType)
 	}
 	if modelName != "" {
 		tx = tx.Where("model_name like ?", modelName)
@@ -127,9 +127,9 @@ func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName
 func GetUserLogs(userId int, logType int, startTimestamp int64, endTimestamp int64, modelName string, tokenName string, startIdx int, num int) (logs []*Log, err error) {
 	var tx *gorm.DB
 	if logType == LogTypeUnknown {
-		tx = DB.Where("user_id = ?", userId)
+		tx = LOG_DB.Where("user_id = ?", userId)
 	} else {
-		tx = DB.Where("user_id = ? and type = ?", userId, logType)
+		tx = LOG_DB.Where("user_id = ? and type = ?", userId, logType)
 	}
 	if modelName != "" {
 		tx = tx.Where("model_name like ?", modelName)
@@ -157,12 +157,12 @@ func GetUserLogs(userId int, logType int, startTimestamp int64, endTimestamp int
 }
 
 func SearchAllLogs(keyword string) (logs []*Log, err error) {
-	err = DB.Where("type = ? or content LIKE ?", keyword, keyword+"%").Order("id desc").Limit(common.MaxRecentItems).Find(&logs).Error
+	err = LOG_DB.Where("type = ? or content LIKE ?", keyword, keyword+"%").Order("id desc").Limit(common.MaxRecentItems).Find(&logs).Error
 	return logs, err
 }
 
 func SearchUserLogs(userId int, keyword string) (logs []*Log, err error) {
-	err = DB.Where("user_id = ? and type = ?", userId, keyword).Order("id desc").Limit(common.MaxRecentItems).Omit("id").Find(&logs).Error
+	err = LOG_DB.Where("user_id = ? and type = ?", userId, keyword).Order("id desc").Limit(common.MaxRecentItems).Omit("id").Find(&logs).Error
 	return logs, err
 }
 
@@ -173,10 +173,10 @@ type Stat struct {
 }
 
 func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, channel int) (stat Stat) {
-	tx := DB.Table("logs").Select("sum(quota) quota")
+	tx := LOG_DB.Table("logs").Select("sum(quota) quota")
 
 	// 为rpm和tpm创建单独的查询
-	rpmTpmQuery := DB.Table("logs").Select("count(*) rpm, sum(prompt_tokens) + sum(completion_tokens) tpm")
+	rpmTpmQuery := LOG_DB.Table("logs").Select("count(*) rpm, sum(prompt_tokens) + sum(completion_tokens) tpm")
 
 	if username != "" {
 		tx = tx.Where("username = ?", username)
@@ -215,7 +215,7 @@ func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelNa
 }
 
 func SumUsedToken(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string) (token int) {
-	tx := DB.Table("logs").Select("ifnull(sum(prompt_tokens),0) + ifnull(sum(completion_tokens),0)")
+	tx := LOG_DB.Table("logs").Select("ifnull(sum(prompt_tokens),0) + ifnull(sum(completion_tokens),0)")
 	if username != "" {
 		tx = tx.Where("username = ?", username)
 	}
@@ -236,6 +236,6 @@ func SumUsedToken(logType int, startTimestamp int64, endTimestamp int64, modelNa
 }
 
 func DeleteOldLog(targetTimestamp int64) (int64, error) {
-	result := DB.Where("created_at < ?", targetTimestamp).Delete(&Log{})
+	result := LOG_DB.Where("created_at < ?", targetTimestamp).Delete(&Log{})
 	return result.RowsAffected, result.Error
 }

+ 116 - 47
model/main.go

@@ -15,6 +15,8 @@ import (
 
 var DB *gorm.DB
 
+var LOG_DB *gorm.DB
+
 func createRootAccountIfNeed() error {
 	var user User
 	//if user.Status != common.UserStatusEnabled {
@@ -38,9 +40,9 @@ func createRootAccountIfNeed() error {
 	return nil
 }
 
-func chooseDB() (*gorm.DB, error) {
-	if os.Getenv("SQL_DSN") != "" {
-		dsn := os.Getenv("SQL_DSN")
+func chooseDB(envName string) (*gorm.DB, error) {
+	dsn := os.Getenv(envName)
+	if dsn != "" {
 		if strings.HasPrefix(dsn, "postgres://") {
 			// Use PostgreSQL
 			common.SysLog("using PostgreSQL as database")
@@ -52,6 +54,13 @@ func chooseDB() (*gorm.DB, error) {
 				PrepareStmt: true, // precompile SQL
 			})
 		}
+		if strings.HasPrefix(dsn, "local") {
+			common.SysLog("SQL_DSN not set, using SQLite as database")
+			common.UsingSQLite = true
+			return gorm.Open(sqlite.Open(common.SQLitePath), &gorm.Config{
+				PrepareStmt: true, // precompile SQL
+			})
+		}
 		// Use MySQL
 		common.SysLog("using MySQL as database")
 		// check parseTime
@@ -76,7 +85,7 @@ func chooseDB() (*gorm.DB, error) {
 }
 
 func InitDB() (err error) {
-	db, err := chooseDB()
+	db, err := chooseDB("SQL_DSN")
 	if err == nil {
 		if common.DebugEnabled {
 			db = db.Debug()
@@ -100,52 +109,44 @@ func InitDB() (err error) {
 		//	_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY status VARCHAR(20);")   // TODO: delete this line when most users have upgraded
 		//}
 		common.SysLog("database migration started")
-		err = db.AutoMigrate(&Channel{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Token{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&User{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Option{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Redemption{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Ability{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Log{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&Midjourney{})
-		if err != nil {
-			return err
-		}
-		err = db.AutoMigrate(&TopUp{})
-		if err != nil {
-			return err
+		err = migrateDB()
+		return err
+	} else {
+		common.FatalLog(err)
+	}
+	return err
+}
+
+func InitLogDB() (err error) {
+	if os.Getenv("LOG_SQL_DSN") == "" {
+		LOG_DB = DB
+		return
+	}
+	db, err := chooseDB("LOG_SQL_DSN")
+	if err == nil {
+		if common.DebugEnabled {
+			db = db.Debug()
 		}
-		err = db.AutoMigrate(&QuotaData{})
+		LOG_DB = db
+		sqlDB, err := LOG_DB.DB()
 		if err != nil {
 			return err
 		}
-		err = db.AutoMigrate(&Task{})
-		if err != nil {
-			return err
+		sqlDB.SetMaxIdleConns(common.GetEnvOrDefault("SQL_MAX_IDLE_CONNS", 100))
+		sqlDB.SetMaxOpenConns(common.GetEnvOrDefault("SQL_MAX_OPEN_CONNS", 1000))
+		sqlDB.SetConnMaxLifetime(time.Second * time.Duration(common.GetEnvOrDefault("SQL_MAX_LIFETIME", 60)))
+
+		if !common.IsMasterNode {
+			return nil
 		}
-		common.SysLog("database migrated")
-		err = createRootAccountIfNeed()
+		//if common.UsingMySQL {
+		//	_, _ = sqlDB.Exec("DROP INDEX idx_channels_key ON channels;")             // TODO: delete this line when most users have upgraded
+		//	_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY action VARCHAR(40);")   // TODO: delete this line when most users have upgraded
+		//	_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY progress VARCHAR(30);") // TODO: delete this line when most users have upgraded
+		//	_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY status VARCHAR(20);")   // TODO: delete this line when most users have upgraded
+		//}
+		common.SysLog("database migration started")
+		err = migrateLOGDB()
 		return err
 	} else {
 		common.FatalLog(err)
@@ -153,8 +154,66 @@ func InitDB() (err error) {
 	return err
 }
 
-func CloseDB() error {
-	sqlDB, err := DB.DB()
+func migrateDB() error {
+	err := DB.AutoMigrate(&Channel{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Token{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&User{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Option{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Redemption{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Ability{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Log{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Midjourney{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&TopUp{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&QuotaData{})
+	if err != nil {
+		return err
+	}
+	err = DB.AutoMigrate(&Task{})
+	if err != nil {
+		return err
+	}
+	common.SysLog("database migrated")
+	err = createRootAccountIfNeed()
+	return err
+}
+
+func migrateLOGDB() error {
+	var err error
+	if err = LOG_DB.AutoMigrate(&Log{}); err != nil {
+		return err
+	}
+	return nil
+}
+
+func closeDB(db *gorm.DB) error {
+	sqlDB, err := db.DB()
 	if err != nil {
 		return err
 	}
@@ -162,6 +221,16 @@ func CloseDB() error {
 	return err
 }
 
+func CloseDB() error {
+	if LOG_DB != DB {
+		err := closeDB(LOG_DB)
+		if err != nil {
+			return err
+		}
+	}
+	return closeDB(DB)
+}
+
 var (
 	lastPingTime time.Time
 	pingMutex    sync.Mutex