Procházet zdrojové kódy

feat: deprecated fron log query (#147)

* feat: deprecated fron log query

* fix: ci
zijiren před 8 měsíci
rodič
revize
320c9725dc

+ 4 - 24
core/controller/dashboard.go

@@ -148,11 +148,8 @@ func fillGaps(data []*model.ChartData, start, end time.Time, t model.TimeSpanTyp
 //	@Param			channel			query		int		false	"Channel ID"
 //	@Param			type			query		string	false	"Type of time span (day, week, month, two_week)"
 //	@Param			model			query		string	false	"Model name"
-//	@Param			result_only		query		bool	false	"Only return result"
-//	@Param			token_usage		query		bool	false	"Token usage"
 //	@Param			start_timestamp	query		int64	false	"Start second timestamp"
 //	@Param			end_timestamp	query		int64	false	"End second timestamp"
-//	@Param			from_log		query		bool	false	"From log"
 //	@Param			timezone		query		string	false	"Timezone, default is Local"
 //	@Success		200				{object}	middleware.APIResponse{data=model.DashboardResponse}
 //	@Router			/api/dashboard [get]
@@ -165,14 +162,11 @@ func GetDashboard(c *gin.Context) {
 	timezoneLocation, _ := time.LoadLocation(c.DefaultQuery("timezone", "Local"))
 	start, end, timeSpan := getDashboardTime(c.Query("type"), startTimestamp, endTimestamp, timezoneLocation)
 	modelName := c.Query("model")
-	resultOnly, _ := strconv.ParseBool(c.Query("result_only"))
-	tokenUsage, _ := strconv.ParseBool(c.Query("token_usage"))
 	channelID, _ := strconv.Atoi(c.Query("channel"))
-	fromLog, _ := strconv.ParseBool(c.Query("from_log"))
 
 	needRPM := channelID != 0
 
-	dashboards, err := model.GetDashboardData(group, start, end, modelName, channelID, timeSpan, resultOnly, needRPM, tokenUsage, fromLog, timezoneLocation)
+	dashboards, err := model.GetDashboardData(group, start, end, modelName, channelID, timeSpan, needRPM, timezoneLocation)
 	if err != nil {
 		middleware.ErrorResponse(c, http.StatusOK, err.Error())
 		return
@@ -203,11 +197,8 @@ func GetDashboard(c *gin.Context) {
 //	@Param			type			query		string	false	"Type of time span (day, week, month, two_week)"
 //	@Param			token_name		query		string	false	"Token name"
 //	@Param			model			query		string	false	"Model or *"
-//	@Param			result_only		query		bool	false	"Only return result"
-//	@Param			token_usage		query		bool	false	"Token usage"
 //	@Param			start_timestamp	query		int64	false	"Start second timestamp"
 //	@Param			end_timestamp	query		int64	false	"End second timestamp"
-//	@Param			from_log		query		bool	false	"From log"
 //	@Param			timezone		query		string	false	"Timezone, default is Local"
 //	@Success		200				{object}	middleware.APIResponse{data=model.GroupDashboardResponse}
 //	@Router			/api/dashboard/{group} [get]
@@ -226,13 +217,10 @@ func GetGroupDashboard(c *gin.Context) {
 	start, end, timeSpan := getDashboardTime(c.Query("type"), startTimestamp, endTimestamp, timezoneLocation)
 	tokenName := c.Query("token_name")
 	modelName := c.Query("model")
-	resultOnly, _ := strconv.ParseBool(c.Query("result_only"))
-	tokenUsage, _ := strconv.ParseBool(c.Query("token_usage"))
-	fromLog, _ := strconv.ParseBool(c.Query("from_log"))
 
 	needRPM := tokenName != ""
 
-	dashboards, err := model.GetGroupDashboardData(group, start, end, tokenName, modelName, timeSpan, resultOnly, needRPM, tokenUsage, fromLog, timezoneLocation)
+	dashboards, err := model.GetGroupDashboardData(group, start, end, tokenName, modelName, timeSpan, needRPM, timezoneLocation)
 	if err != nil {
 		middleware.ErrorResponse(c, http.StatusOK, "failed to get statistics")
 		return
@@ -305,17 +293,13 @@ func GetGroupDashboardModels(c *gin.Context) {
 //	@Param			channel			query		int		false	"Channel ID"
 //	@Param			start_timestamp	query		int64	false	"Start timestamp"
 //	@Param			end_timestamp	query		int64	false	"End timestamp"
-//	@Param			token_usage		query		bool	false	"Token usage"
-//	@Param			from_log		query		bool	false	"From log"
 //	@Success		200				{object}	middleware.APIResponse{data=[]model.ModelCostRank}
 //	@Router			/api/model_cost_rank [get]
 func GetModelCostRank(c *gin.Context) {
 	group := c.Query("group")
 	channelID, _ := strconv.Atoi(c.Query("channel"))
 	startTime, endTime := parseTimeRange(c)
-	tokenUsage, _ := strconv.ParseBool(c.Query("token_usage"))
-	fromLog, _ := strconv.ParseBool(c.Query("from_log"))
-	models, err := model.GetModelCostRank(group, channelID, startTime, endTime, tokenUsage, fromLog)
+	models, err := model.GetModelCostRank(group, channelID, startTime, endTime)
 	if err != nil {
 		middleware.ErrorResponse(c, http.StatusOK, err.Error())
 		return
@@ -333,8 +317,6 @@ func GetModelCostRank(c *gin.Context) {
 //	@Param			group			path		string	true	"Group"
 //	@Param			start_timestamp	query		int64	false	"Start timestamp"
 //	@Param			end_timestamp	query		int64	false	"End timestamp"
-//	@Param			token_usage		query		bool	false	"Token usage"
-//	@Param			from_log		query		bool	false	"From log"
 //	@Success		200				{object}	middleware.APIResponse{data=[]model.ModelCostRank}
 //	@Router			/api/model_cost_rank/{group} [get]
 func GetGroupModelCostRank(c *gin.Context) {
@@ -344,9 +326,7 @@ func GetGroupModelCostRank(c *gin.Context) {
 		return
 	}
 	startTime, endTime := parseTimeRange(c)
-	tokenUsage, _ := strconv.ParseBool(c.Query("token_usage"))
-	fromLog, _ := strconv.ParseBool(c.Query("from_log"))
-	models, err := model.GetModelCostRank(group, 0, startTime, endTime, tokenUsage, fromLog)
+	models, err := model.GetModelCostRank(group, 0, startTime, endTime)
 	if err != nil {
 		middleware.ErrorResponse(c, http.StatusOK, err.Error())
 		return

+ 0 - 63
core/docs/docs.go

@@ -1001,18 +1001,6 @@ const docTemplate = `{
                         "name": "model",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "Only return result",
-                        "name": "result_only",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
                     {
                         "type": "integer",
                         "description": "Start second timestamp",
@@ -1025,12 +1013,6 @@ const docTemplate = `{
                         "name": "end_timestamp",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
-                    },
                     {
                         "type": "string",
                         "description": "Timezone, default is Local",
@@ -1101,18 +1083,6 @@ const docTemplate = `{
                         "name": "model",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "Only return result",
-                        "name": "result_only",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
                     {
                         "type": "integer",
                         "description": "Start second timestamp",
@@ -1125,12 +1095,6 @@ const docTemplate = `{
                         "name": "end_timestamp",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
-                    },
                     {
                         "type": "string",
                         "description": "Timezone, default is Local",
@@ -4298,18 +4262,6 @@ const docTemplate = `{
                         "description": "End timestamp",
                         "name": "end_timestamp",
                         "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
                     }
                 ],
                 "responses": {
@@ -4371,18 +4323,6 @@ const docTemplate = `{
                         "description": "End timestamp",
                         "name": "end_timestamp",
                         "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
                     }
                 ],
                 "responses": {
@@ -8566,9 +8506,6 @@ const docTemplate = `{
                 "retry_times": {
                     "type": "integer"
                 },
-                "timestamp_trunc_by_hour": {
-                    "type": "integer"
-                },
                 "token_id": {
                     "type": "integer"
                 },

+ 0 - 63
core/docs/swagger.json

@@ -992,18 +992,6 @@
                         "name": "model",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "Only return result",
-                        "name": "result_only",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
                     {
                         "type": "integer",
                         "description": "Start second timestamp",
@@ -1016,12 +1004,6 @@
                         "name": "end_timestamp",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
-                    },
                     {
                         "type": "string",
                         "description": "Timezone, default is Local",
@@ -1092,18 +1074,6 @@
                         "name": "model",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "Only return result",
-                        "name": "result_only",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
                     {
                         "type": "integer",
                         "description": "Start second timestamp",
@@ -1116,12 +1086,6 @@
                         "name": "end_timestamp",
                         "in": "query"
                     },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
-                    },
                     {
                         "type": "string",
                         "description": "Timezone, default is Local",
@@ -4289,18 +4253,6 @@
                         "description": "End timestamp",
                         "name": "end_timestamp",
                         "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
                     }
                 ],
                 "responses": {
@@ -4362,18 +4314,6 @@
                         "description": "End timestamp",
                         "name": "end_timestamp",
                         "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "Token usage",
-                        "name": "token_usage",
-                        "in": "query"
-                    },
-                    {
-                        "type": "boolean",
-                        "description": "From log",
-                        "name": "from_log",
-                        "in": "query"
                     }
                 ],
                 "responses": {
@@ -8557,9 +8497,6 @@
                 "retry_times": {
                     "type": "integer"
                 },
-                "timestamp_trunc_by_hour": {
-                    "type": "integer"
-                },
                 "token_id": {
                     "type": "integer"
                 },

+ 0 - 42
core/docs/swagger.yaml

@@ -945,8 +945,6 @@ definitions:
         type: string
       retry_times:
         type: integer
-      timestamp_trunc_by_hour:
-        type: integer
       token_id:
         type: integer
       token_name:
@@ -2010,14 +2008,6 @@ paths:
         in: query
         name: model
         type: string
-      - description: Only return result
-        in: query
-        name: result_only
-        type: boolean
-      - description: Token usage
-        in: query
-        name: token_usage
-        type: boolean
       - description: Start second timestamp
         in: query
         name: start_timestamp
@@ -2026,10 +2016,6 @@ paths:
         in: query
         name: end_timestamp
         type: integer
-      - description: From log
-        in: query
-        name: from_log
-        type: boolean
       - description: Timezone, default is Local
         in: query
         name: timezone
@@ -2072,14 +2058,6 @@ paths:
         in: query
         name: model
         type: string
-      - description: Only return result
-        in: query
-        name: result_only
-        type: boolean
-      - description: Token usage
-        in: query
-        name: token_usage
-        type: boolean
       - description: Start second timestamp
         in: query
         name: start_timestamp
@@ -2088,10 +2066,6 @@ paths:
         in: query
         name: end_timestamp
         type: integer
-      - description: From log
-        in: query
-        name: from_log
-        type: boolean
       - description: Timezone, default is Local
         in: query
         name: timezone
@@ -4008,14 +3982,6 @@ paths:
         in: query
         name: end_timestamp
         type: integer
-      - description: Token usage
-        in: query
-        name: token_usage
-        type: boolean
-      - description: From log
-        in: query
-        name: from_log
-        type: boolean
       produces:
       - application/json
       responses:
@@ -4052,14 +4018,6 @@ paths:
         in: query
         name: end_timestamp
         type: integer
-      - description: Token usage
-        in: query
-        name: token_usage
-        type: boolean
-      - description: From log
-        in: query
-        name: from_log
-        type: boolean
       produces:
       - application/json
       responses:

+ 37 - 219
core/model/log.go

@@ -114,29 +114,28 @@ func (u *Usage) Add(other *Usage) {
 }
 
 type Log struct {
-	RequestDetail        *RequestDetail  `gorm:"foreignKey:LogID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"request_detail,omitempty"`
-	RequestAt            time.Time       `gorm:"index"                                                          json:"request_at"`
-	RetryAt              time.Time       `json:"retry_at,omitempty"`
-	TTFBMilliseconds     ZeroNullInt64   `json:"ttfb_milliseconds,omitempty"`
-	TimestampTruncByHour int64           `json:"timestamp_trunc_by_hour"`
-	CreatedAt            time.Time       `gorm:"autoCreateTime;index"                                           json:"created_at"`
-	TokenName            string          `json:"token_name,omitempty"`
-	Endpoint             EmptyNullString `json:"endpoint,omitempty"`
-	Content              EmptyNullString `gorm:"type:text"                                                      json:"content,omitempty"`
-	GroupID              string          `json:"group,omitempty"`
-	Model                string          `json:"model"`
-	RequestID            EmptyNullString `gorm:"index:,where:request_id is not null"                            json:"request_id"`
-	ID                   int             `gorm:"primaryKey"                                                     json:"id"`
-	TokenID              int             `gorm:"index"                                                          json:"token_id,omitempty"`
-	ChannelID            int             `json:"channel,omitempty"`
-	Code                 int             `gorm:"index"                                                          json:"code,omitempty"`
-	Mode                 int             `json:"mode,omitempty"`
-	IP                   EmptyNullString `gorm:"index:,where:ip is not null"                                    json:"ip,omitempty"`
-	RetryTimes           ZeroNullInt64   `json:"retry_times,omitempty"`
-	DownstreamResult     bool            `json:"downstream_result,omitempty"`
-	Price                Price           `gorm:"embedded"                                                       json:"price,omitempty"`
-	Usage                Usage           `gorm:"embedded"                                                       json:"usage,omitempty"`
-	UsedAmount           float64         `json:"used_amount,omitempty"`
+	RequestDetail    *RequestDetail  `gorm:"foreignKey:LogID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"request_detail,omitempty"`
+	RequestAt        time.Time       `gorm:"index"                                                          json:"request_at"`
+	RetryAt          time.Time       `json:"retry_at,omitempty"`
+	TTFBMilliseconds ZeroNullInt64   `json:"ttfb_milliseconds,omitempty"`
+	CreatedAt        time.Time       `gorm:"autoCreateTime;index"                                           json:"created_at"`
+	TokenName        string          `json:"token_name,omitempty"`
+	Endpoint         EmptyNullString `json:"endpoint,omitempty"`
+	Content          EmptyNullString `gorm:"type:text"                                                      json:"content,omitempty"`
+	GroupID          string          `json:"group,omitempty"`
+	Model            string          `json:"model"`
+	RequestID        EmptyNullString `gorm:"index:,where:request_id is not null"                            json:"request_id"`
+	ID               int             `gorm:"primaryKey"                                                     json:"id"`
+	TokenID          int             `gorm:"index"                                                          json:"token_id,omitempty"`
+	ChannelID        int             `json:"channel,omitempty"`
+	Code             int             `gorm:"index"                                                          json:"code,omitempty"`
+	Mode             int             `json:"mode,omitempty"`
+	IP               EmptyNullString `gorm:"index:,where:ip is not null"                                    json:"ip,omitempty"`
+	RetryTimes       ZeroNullInt64   `json:"retry_times,omitempty"`
+	DownstreamResult bool            `json:"downstream_result,omitempty"`
+	Price            Price           `gorm:"embedded"                                                       json:"price,omitempty"`
+	Usage            Usage           `gorm:"embedded"                                                       json:"usage,omitempty"`
+	UsedAmount       float64         `json:"used_amount,omitempty"`
 }
 
 func CreateLogIndexes(db *gorm.DB) error {
@@ -151,11 +150,6 @@ func CreateLogIndexes(db *gorm.DB) error {
 			// used by global search logs
 			"CREATE INDEX IF NOT EXISTS idx_channel_model_reqat ON logs (channel_id, model, request_at DESC)",
 
-			// global hour indexes, used by global dashboard
-			"CREATE INDEX IF NOT EXISTS idx_model_trunchour ON logs (model, timestamp_trunc_by_hour)",
-			"CREATE INDEX IF NOT EXISTS idx_channel_trunchour ON logs (channel_id, timestamp_trunc_by_hour)",
-			"CREATE INDEX IF NOT EXISTS idx_channel_model_trunchour ON logs (channel_id, model, timestamp_trunc_by_hour)",
-
 			// used by search group logs
 			"CREATE INDEX IF NOT EXISTS idx_group_reqat ON logs (group_id, request_at DESC)",
 			// used by search group logs
@@ -164,12 +158,6 @@ func CreateLogIndexes(db *gorm.DB) error {
 			"CREATE INDEX IF NOT EXISTS idx_group_model_reqat ON logs (group_id, model, request_at DESC)",
 			// used by search group logs
 			"CREATE INDEX IF NOT EXISTS idx_group_token_model_reqat ON logs (group_id, token_name, model, request_at DESC)",
-
-			// hour indexes, used by dashboard
-			"CREATE INDEX IF NOT EXISTS idx_group_trunchour ON logs (group_id, timestamp_trunc_by_hour DESC)",
-			"CREATE INDEX IF NOT EXISTS idx_group_model_trunchour ON logs (group_id, model, timestamp_trunc_by_hour DESC)",
-			"CREATE INDEX IF NOT EXISTS idx_group_token_trunchour ON logs (group_id, token_name, timestamp_trunc_by_hour DESC)",
-			"CREATE INDEX IF NOT EXISTS idx_group_model_token_trunchour ON logs (group_id, model, token_name, timestamp_trunc_by_hour DESC)",
 		}
 	} else {
 		indexes = []string{
@@ -180,11 +168,6 @@ func CreateLogIndexes(db *gorm.DB) error {
 			// used by global search logs
 			"CREATE INDEX IF NOT EXISTS idx_channel_model_reqat ON logs (channel_id, model, request_at DESC) INCLUDE (code, downstream_result)",
 
-			// global hour indexes, used by global dashboard
-			"CREATE INDEX IF NOT EXISTS idx_model_trunchour ON logs (model, timestamp_trunc_by_hour) INCLUDE (downstream_result)",
-			"CREATE INDEX IF NOT EXISTS idx_channel_trunchour ON logs (channel_id, timestamp_trunc_by_hour) INCLUDE (downstream_result)",
-			"CREATE INDEX IF NOT EXISTS idx_channel_model_trunchour ON logs (channel_id, model, timestamp_trunc_by_hour) INCLUDE (downstream_result)",
-
 			// used by search group logs
 			"CREATE INDEX IF NOT EXISTS idx_group_reqat ON logs (group_id, request_at DESC) INCLUDE (code, downstream_result)",
 			// used by search group logs
@@ -193,12 +176,6 @@ func CreateLogIndexes(db *gorm.DB) error {
 			"CREATE INDEX IF NOT EXISTS idx_group_model_reqat ON logs (group_id, model, request_at DESC) INCLUDE (code, downstream_result)",
 			// used by search group logs
 			"CREATE INDEX IF NOT EXISTS idx_group_token_model_reqat ON logs (group_id, token_name, model, request_at DESC) INCLUDE (code, downstream_result)",
-
-			// hour indexes, used by dashboard
-			"CREATE INDEX IF NOT EXISTS idx_group_trunchour ON logs (group_id, timestamp_trunc_by_hour DESC) INCLUDE (downstream_result)",
-			"CREATE INDEX IF NOT EXISTS idx_group_model_trunchour ON logs (group_id, model, timestamp_trunc_by_hour DESC) INCLUDE (downstream_result)",
-			"CREATE INDEX IF NOT EXISTS idx_group_token_trunchour ON logs (group_id, token_name, timestamp_trunc_by_hour DESC) INCLUDE (downstream_result)",
-			"CREATE INDEX IF NOT EXISTS idx_group_model_token_trunchour ON logs (group_id, model, token_name, timestamp_trunc_by_hour DESC) INCLUDE (downstream_result)",
 		}
 	}
 
@@ -225,9 +202,6 @@ func (l *Log) BeforeCreate(_ *gorm.DB) (err error) {
 	if l.RequestAt.IsZero() {
 		l.RequestAt = l.CreatedAt
 	}
-	if l.TimestampTruncByHour == 0 {
-		l.TimestampTruncByHour = l.RequestAt.Truncate(time.Hour).Unix()
-	}
 	return
 }
 
@@ -1122,71 +1096,6 @@ const (
 	TimeSpanHour TimeSpanType = "hour"
 )
 
-func getChartDataFromLog(
-	group string,
-	start, end time.Time,
-	tokenName, modelName string,
-	channelID int,
-	timeSpan TimeSpanType,
-	resultOnly bool, tokenUsage bool,
-	timezone *time.Location,
-) ([]*ChartData, error) {
-	var query *gorm.DB
-	if tokenUsage {
-		query = LogDB.Table("logs").
-			Select("timestamp_trunc_by_hour as timestamp, count(*) as request_count, sum(used_amount) as used_amount, sum(case when code != 200 then 1 else 0 end) as exception_count, sum(input_tokens) as input_tokens, sum(output_tokens) as output_tokens, sum(cached_tokens) as cached_tokens, sum(cache_creation_tokens) as cache_creation_tokens, sum(total_tokens) as total_tokens, sum(web_search_count) as web_search_count").
-			Group("timestamp").
-			Order("timestamp ASC")
-	} else {
-		query = LogDB.Table("logs").
-			Select("timestamp_trunc_by_hour as timestamp, count(*) as request_count, sum(used_amount) as used_amount, sum(case when code != 200 then 1 else 0 end) as exception_count").
-			Group("timestamp").
-			Order("timestamp ASC")
-	}
-
-	if group == "" {
-		query = query.Where("group_id = ''")
-	} else if group != "*" {
-		query = query.Where("group_id = ?", group)
-	}
-
-	if channelID != 0 {
-		query = query.Where("channel_id = ?", channelID)
-	}
-	if modelName != "" {
-		query = query.Where("model = ?", modelName)
-	}
-	if tokenName != "" {
-		query = query.Where("token_name = ?", tokenName)
-	}
-
-	switch {
-	case !start.IsZero() && !end.IsZero():
-		query = query.Where("timestamp_trunc_by_hour BETWEEN ? AND ?", start.Unix(), end.Unix())
-	case !start.IsZero():
-		query = query.Where("timestamp_trunc_by_hour >= ?", start.Unix())
-	case !end.IsZero():
-		query = query.Where("timestamp_trunc_by_hour <= ?", end.Unix())
-	}
-
-	if resultOnly {
-		query = query.Where("downstream_result = true")
-	}
-
-	var chartData []*ChartData
-	err := query.Scan(&chartData).Error
-	if err != nil {
-		return nil, err
-	}
-
-	// If timeSpan is day, aggregate hour data into day data
-	if timeSpan == TimeSpanDay && len(chartData) > 0 {
-		return aggregateHourDataToDay(chartData, timezone), nil
-	}
-
-	return chartData, nil
-}
-
 // aggregateHourDataToDay converts hourly chart data into daily aggregated data
 func aggregateHourDataToDay(hourlyData []*ChartData, timezone *time.Location) []*ChartData {
 	dayData := make(map[int64]*ChartData)
@@ -1356,10 +1265,7 @@ func GetDashboardData(
 	modelName string,
 	channelID int,
 	timeSpan TimeSpanType,
-	resultOnly bool,
 	needRPM bool,
-	tokenUsage bool,
-	fromLog bool,
 	timezone *time.Location,
 ) (*DashboardResponse, error) {
 	if end.IsZero() {
@@ -1377,19 +1283,11 @@ func GetDashboardData(
 
 	g := new(errgroup.Group)
 
-	if fromLog {
-		g.Go(func() error {
-			var err error
-			chartData, err = getChartDataFromLog(group, start, end, "", modelName, channelID, timeSpan, resultOnly, tokenUsage, timezone)
-			return err
-		})
-	} else {
-		g.Go(func() error {
-			var err error
-			chartData, err = getChartData(group, start, end, "", modelName, channelID, timeSpan, timezone)
-			return err
-		})
-	}
+	g.Go(func() error {
+		var err error
+		chartData, err = getChartData(group, start, end, "", modelName, channelID, timeSpan, timezone)
+		return err
+	})
 
 	if needRPM {
 		g.Go(func() error {
@@ -1405,19 +1303,11 @@ func GetDashboardData(
 		return err
 	})
 
-	if fromLog {
-		g.Go(func() error {
-			var err error
-			channels, err = GetUsedChannelsFromLog(group, start, end)
-			return err
-		})
-	} else {
-		g.Go(func() error {
-			var err error
-			channels, err = GetUsedChannels(group, start, end)
-			return err
-		})
-	}
+	g.Go(func() error {
+		var err error
+		channels, err = GetUsedChannels(group, start, end)
+		return err
+	})
 
 	if err := g.Wait(); err != nil {
 		return nil, err
@@ -1437,10 +1327,7 @@ func GetGroupDashboardData(
 	tokenName string,
 	modelName string,
 	timeSpan TimeSpanType,
-	resultOnly bool,
 	needRPM bool,
-	tokenUsage bool,
-	fromLog bool,
 	timezone *time.Location,
 ) (*GroupDashboardResponse, error) {
 	if group == "" || group == "*" {
@@ -1463,19 +1350,11 @@ func GetGroupDashboardData(
 
 	g := new(errgroup.Group)
 
-	if fromLog {
-		g.Go(func() error {
-			var err error
-			chartData, err = getChartDataFromLog(group, start, end, tokenName, modelName, 0, timeSpan, resultOnly, tokenUsage, timezone)
-			return err
-		})
-	} else {
-		g.Go(func() error {
-			var err error
-			chartData, err = getChartData(group, start, end, tokenName, modelName, 0, timeSpan, timezone)
-			return err
-		})
-	}
+	g.Go(func() error {
+		var err error
+		chartData, err = getChartData(group, start, end, tokenName, modelName, 0, timeSpan, timezone)
+		return err
+	})
 
 	g.Go(func() error {
 		var err error
@@ -1543,67 +1422,6 @@ type ModelCostRank struct {
 	WebSearchCount      int64   `json:"web_search_count"`
 }
 
-func GetModelCostRank(group string, channelID int, start, end time.Time, tokenUsage bool, fromLog bool) ([]*ModelCostRank, error) {
-	if fromLog {
-		return getModelCostRankFromLog(group, channelID, start, end, tokenUsage)
-	}
-	return getModelCostRank(group, channelID, start, end)
-}
-
-func getModelCostRankFromLog(group string, channelID int, start, end time.Time, tokenUsage bool) ([]*ModelCostRank, error) {
-	var ranks []*ModelCostRank
-
-	var query *gorm.DB
-	if tokenUsage {
-		query = LogDB.Model(&Log{}).
-			Select("model, SUM(used_amount) as used_amount, SUM(input_tokens) as input_tokens, SUM(output_tokens) as output_tokens, SUM(cached_tokens) as cached_tokens, SUM(cache_creation_tokens) as cache_creation_tokens, SUM(total_tokens) as total_tokens, COUNT(*) as request_count, SUM(web_search_count) as web_search_count").
-			Group("model")
-	} else {
-		query = LogDB.Model(&Log{}).
-			Select("model, SUM(used_amount) as used_amount, COUNT(*) as request_count").
-			Group("model")
-	}
-
-	if group == "" {
-		query = query.Where("group_id = ''")
-	} else if group != "*" {
-		query = query.Where("group_id = ?", group)
-	}
-
-	if channelID != 0 {
-		query = query.Where("channel_id = ?", channelID)
-	}
-
-	switch {
-	case !start.IsZero() && !end.IsZero():
-		query = query.Where("request_at BETWEEN ? AND ?", start, end)
-	case !start.IsZero():
-		query = query.Where("request_at >= ?", start)
-	case !end.IsZero():
-		query = query.Where("request_at <= ?", end)
-	}
-
-	err := query.Scan(&ranks).Error
-	if err != nil {
-		return nil, err
-	}
-
-	slices.SortFunc(ranks, func(a, b *ModelCostRank) int {
-		if a.UsedAmount != b.UsedAmount {
-			return cmp.Compare(b.UsedAmount, a.UsedAmount)
-		}
-		if a.TotalTokens != b.TotalTokens {
-			return cmp.Compare(b.TotalTokens, a.TotalTokens)
-		}
-		if a.RequestCount != b.RequestCount {
-			return cmp.Compare(b.RequestCount, a.RequestCount)
-		}
-		return cmp.Compare(a.Model, b.Model)
-	})
-
-	return ranks, nil
-}
-
 func GetIPGroups(threshold int, start, end time.Time) (map[string][]string, error) {
 	if threshold < 1 {
 		threshold = 1

+ 1 - 1
core/model/summary.go

@@ -274,7 +274,7 @@ func getLogGroupByValues[T cmp.Ordered](field string, group string, start, end t
 	return values, nil
 }
 
-func getModelCostRank(group string, channelID int, start, end time.Time) ([]*ModelCostRank, error) {
+func GetModelCostRank(group string, channelID int, start, end time.Time) ([]*ModelCostRank, error) {
 	var ranks []*ModelCostRank
 
 	var query *gorm.DB