mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 15:53:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			185 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package model
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"gorm.io/gorm"
 | 
						|
	"one-api/common"
 | 
						|
)
 | 
						|
 | 
						|
type Log struct {
 | 
						|
	Id               int    `json:"id;index:idx_created_at_id,priority:1"`
 | 
						|
	UserId           int    `json:"user_id" gorm:"index"`
 | 
						|
	CreatedAt        int64  `json:"created_at" gorm:"bigint;index:idx_created_at_id,priority:2;index:idx_created_at_type"`
 | 
						|
	Type             int    `json:"type" gorm:"index:idx_created_at_type"`
 | 
						|
	Content          string `json:"content"`
 | 
						|
	Username         string `json:"username" gorm:"index:index_username_model_name,priority:2;default:''"`
 | 
						|
	TokenName        string `json:"token_name" gorm:"index;default:''"`
 | 
						|
	ModelName        string `json:"model_name" gorm:"index;index:index_username_model_name,priority:1;default:''"`
 | 
						|
	Quota            int    `json:"quota" gorm:"default:0"`
 | 
						|
	PromptTokens     int    `json:"prompt_tokens" gorm:"default:0"`
 | 
						|
	CompletionTokens int    `json:"completion_tokens" gorm:"default:0"`
 | 
						|
	ChannelId        int    `json:"channel" gorm:"index"`
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	LogTypeUnknown = iota
 | 
						|
	LogTypeTopup
 | 
						|
	LogTypeConsume
 | 
						|
	LogTypeManage
 | 
						|
	LogTypeSystem
 | 
						|
)
 | 
						|
 | 
						|
func RecordLog(userId int, logType int, content string) {
 | 
						|
	if logType == LogTypeConsume && !common.LogConsumeEnabled {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	log := &Log{
 | 
						|
		UserId:    userId,
 | 
						|
		Username:  GetUsernameById(userId),
 | 
						|
		CreatedAt: common.GetTimestamp(),
 | 
						|
		Type:      logType,
 | 
						|
		Content:   content,
 | 
						|
	}
 | 
						|
	err := DB.Create(log).Error
 | 
						|
	if err != nil {
 | 
						|
		common.SysError("failed to record log: " + err.Error())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func RecordConsumeLog(ctx context.Context, userId int, channelId int, promptTokens int, completionTokens int, modelName string, tokenName string, quota int, content string) {
 | 
						|
	common.LogInfo(ctx, fmt.Sprintf("record consume log: userId=%d, channelId=%d, promptTokens=%d, completionTokens=%d, modelName=%s, tokenName=%s, quota=%d, content=%s", userId, channelId, promptTokens, completionTokens, modelName, tokenName, quota, content))
 | 
						|
	if !common.LogConsumeEnabled {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	log := &Log{
 | 
						|
		UserId:           userId,
 | 
						|
		Username:         GetUsernameById(userId),
 | 
						|
		CreatedAt:        common.GetTimestamp(),
 | 
						|
		Type:             LogTypeConsume,
 | 
						|
		Content:          content,
 | 
						|
		PromptTokens:     promptTokens,
 | 
						|
		CompletionTokens: completionTokens,
 | 
						|
		TokenName:        tokenName,
 | 
						|
		ModelName:        modelName,
 | 
						|
		Quota:            quota,
 | 
						|
		ChannelId:        channelId,
 | 
						|
	}
 | 
						|
	err := DB.Create(log).Error
 | 
						|
	if err != nil {
 | 
						|
		common.LogError(ctx, "failed to record log: "+err.Error())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
	} else {
 | 
						|
		tx = DB.Where("type = ?", logType)
 | 
						|
	}
 | 
						|
	if modelName != "" {
 | 
						|
		tx = tx.Where("model_name = ?", modelName)
 | 
						|
	}
 | 
						|
	if username != "" {
 | 
						|
		tx = tx.Where("username = ?", username)
 | 
						|
	}
 | 
						|
	if tokenName != "" {
 | 
						|
		tx = tx.Where("token_name = ?", tokenName)
 | 
						|
	}
 | 
						|
	if startTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at >= ?", startTimestamp)
 | 
						|
	}
 | 
						|
	if endTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at <= ?", endTimestamp)
 | 
						|
	}
 | 
						|
	if channel != 0 {
 | 
						|
		tx = tx.Where("channel = ?", channel)
 | 
						|
	}
 | 
						|
	err = tx.Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error
 | 
						|
	return logs, err
 | 
						|
}
 | 
						|
 | 
						|
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)
 | 
						|
	} else {
 | 
						|
		tx = DB.Where("user_id = ? and type = ?", userId, logType)
 | 
						|
	}
 | 
						|
	if modelName != "" {
 | 
						|
		tx = tx.Where("model_name = ?", modelName)
 | 
						|
	}
 | 
						|
	if tokenName != "" {
 | 
						|
		tx = tx.Where("token_name = ?", tokenName)
 | 
						|
	}
 | 
						|
	if startTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at >= ?", startTimestamp)
 | 
						|
	}
 | 
						|
	if endTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at <= ?", endTimestamp)
 | 
						|
	}
 | 
						|
	err = tx.Order("id desc").Limit(num).Offset(startIdx).Omit("id").Find(&logs).Error
 | 
						|
	return logs, err
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
	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
 | 
						|
	return logs, err
 | 
						|
}
 | 
						|
 | 
						|
func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, channel int) (quota int) {
 | 
						|
	tx := DB.Table("logs").Select("ifnull(sum(quota),0)")
 | 
						|
	if username != "" {
 | 
						|
		tx = tx.Where("username = ?", username)
 | 
						|
	}
 | 
						|
	if tokenName != "" {
 | 
						|
		tx = tx.Where("token_name = ?", tokenName)
 | 
						|
	}
 | 
						|
	if startTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at >= ?", startTimestamp)
 | 
						|
	}
 | 
						|
	if endTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at <= ?", endTimestamp)
 | 
						|
	}
 | 
						|
	if modelName != "" {
 | 
						|
		tx = tx.Where("model_name = ?", modelName)
 | 
						|
	}
 | 
						|
	if channel != 0 {
 | 
						|
		tx = tx.Where("channel = ?", channel)
 | 
						|
	}
 | 
						|
	tx.Where("type = ?", LogTypeConsume).Scan("a)
 | 
						|
	return quota
 | 
						|
}
 | 
						|
 | 
						|
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)")
 | 
						|
	if username != "" {
 | 
						|
		tx = tx.Where("username = ?", username)
 | 
						|
	}
 | 
						|
	if tokenName != "" {
 | 
						|
		tx = tx.Where("token_name = ?", tokenName)
 | 
						|
	}
 | 
						|
	if startTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at >= ?", startTimestamp)
 | 
						|
	}
 | 
						|
	if endTimestamp != 0 {
 | 
						|
		tx = tx.Where("created_at <= ?", endTimestamp)
 | 
						|
	}
 | 
						|
	if modelName != "" {
 | 
						|
		tx = tx.Where("model_name = ?", modelName)
 | 
						|
	}
 | 
						|
	tx.Where("type = ?", LogTypeConsume).Scan(&token)
 | 
						|
	return token
 | 
						|
}
 | 
						|
 | 
						|
func DeleteOldLog(targetTimestamp int64) (int64, error) {
 | 
						|
	result := DB.Where("created_at < ?", targetTimestamp).Delete(&Log{})
 | 
						|
	return result.RowsAffected, result.Error
 | 
						|
}
 |