fix: keep usage log filters exact unless wildcard is explicit (#5097)
This commit is contained in:
+40
-27
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/QuantumNous/new-api/common"
|
"github.com/QuantumNous/new-api/common"
|
||||||
@@ -16,6 +17,20 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func applyExplicitLogTextFilter(tx *gorm.DB, column string, value string) (*gorm.DB, error) {
|
||||||
|
if value == "" {
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
if strings.Contains(value, "%") {
|
||||||
|
pattern, err := sanitizeLikePattern(value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tx.Where(column+" LIKE ? ESCAPE '!'", pattern), nil
|
||||||
|
}
|
||||||
|
return tx.Where(column+" = ?", value), nil
|
||||||
|
}
|
||||||
|
|
||||||
type Log struct {
|
type Log struct {
|
||||||
Id int `json:"id" gorm:"index:idx_created_at_id,priority:1;index:idx_user_id_id,priority:2"`
|
Id int `json:"id" gorm:"index:idx_created_at_id,priority:1;index:idx_user_id_id,priority:2"`
|
||||||
UserId int `json:"user_id" gorm:"index;index:idx_user_id_id,priority:1"`
|
UserId int `json:"user_id" gorm:"index;index:idx_user_id_id,priority:1"`
|
||||||
@@ -308,14 +323,14 @@ func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName
|
|||||||
tx = LOG_DB.Where("logs.type = ?", logType)
|
tx = LOG_DB.Where("logs.type = ?", logType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if modelName != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "logs.model_name", modelName); err != nil {
|
||||||
tx = tx.Where("logs.model_name like ?", modelName)
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if username != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "logs.username", username); err != nil {
|
||||||
tx = tx.Where("logs.username = ?", username)
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if tokenName != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "logs.token_name", tokenName); err != nil {
|
||||||
tx = tx.Where("logs.token_name = ?", tokenName)
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if requestId != "" {
|
if requestId != "" {
|
||||||
tx = tx.Where("logs.request_id = ?", requestId)
|
tx = tx.Where("logs.request_id = ?", requestId)
|
||||||
@@ -397,15 +412,11 @@ func GetUserLogs(userId int, logType int, startTimestamp int64, endTimestamp int
|
|||||||
tx = LOG_DB.Where("logs.user_id = ? and logs.type = ?", userId, logType)
|
tx = LOG_DB.Where("logs.user_id = ? and logs.type = ?", userId, logType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if modelName != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "logs.model_name", modelName); err != nil {
|
||||||
modelNamePattern, err := sanitizeLikePattern(modelName)
|
return nil, 0, err
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
tx = tx.Where("logs.model_name LIKE ? ESCAPE '!'", modelNamePattern)
|
|
||||||
}
|
}
|
||||||
if tokenName != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "logs.token_name", tokenName); err != nil {
|
||||||
tx = tx.Where("logs.token_name = ?", tokenName)
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if requestId != "" {
|
if requestId != "" {
|
||||||
tx = tx.Where("logs.request_id = ?", requestId)
|
tx = tx.Where("logs.request_id = ?", requestId)
|
||||||
@@ -449,13 +460,17 @@ func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelNa
|
|||||||
// 为rpm和tpm创建单独的查询
|
// 为rpm和tpm创建单独的查询
|
||||||
rpmTpmQuery := LOG_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 != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "username", username); err != nil {
|
||||||
tx = tx.Where("username = ?", username)
|
return stat, err
|
||||||
rpmTpmQuery = rpmTpmQuery.Where("username = ?", username)
|
|
||||||
}
|
}
|
||||||
if tokenName != "" {
|
if rpmTpmQuery, err = applyExplicitLogTextFilter(rpmTpmQuery, "username", username); err != nil {
|
||||||
tx = tx.Where("token_name = ?", tokenName)
|
return stat, err
|
||||||
rpmTpmQuery = rpmTpmQuery.Where("token_name = ?", tokenName)
|
}
|
||||||
|
if tx, err = applyExplicitLogTextFilter(tx, "token_name", tokenName); err != nil {
|
||||||
|
return stat, err
|
||||||
|
}
|
||||||
|
if rpmTpmQuery, err = applyExplicitLogTextFilter(rpmTpmQuery, "token_name", tokenName); err != nil {
|
||||||
|
return stat, err
|
||||||
}
|
}
|
||||||
if startTimestamp != 0 {
|
if startTimestamp != 0 {
|
||||||
tx = tx.Where("created_at >= ?", startTimestamp)
|
tx = tx.Where("created_at >= ?", startTimestamp)
|
||||||
@@ -463,13 +478,11 @@ func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelNa
|
|||||||
if endTimestamp != 0 {
|
if endTimestamp != 0 {
|
||||||
tx = tx.Where("created_at <= ?", endTimestamp)
|
tx = tx.Where("created_at <= ?", endTimestamp)
|
||||||
}
|
}
|
||||||
if modelName != "" {
|
if tx, err = applyExplicitLogTextFilter(tx, "model_name", modelName); err != nil {
|
||||||
modelNamePattern, err := sanitizeLikePattern(modelName)
|
return stat, err
|
||||||
if err != nil {
|
}
|
||||||
return stat, err
|
if rpmTpmQuery, err = applyExplicitLogTextFilter(rpmTpmQuery, "model_name", modelName); err != nil {
|
||||||
}
|
return stat, err
|
||||||
tx = tx.Where("model_name LIKE ? ESCAPE '!'", modelNamePattern)
|
|
||||||
rpmTpmQuery = rpmTpmQuery.Where("model_name LIKE ? ESCAPE '!'", modelNamePattern)
|
|
||||||
}
|
}
|
||||||
if channel != 0 {
|
if channel != 0 {
|
||||||
tx = tx.Where("channel_id = ?", channel)
|
tx = tx.Where("channel_id = ?", channel)
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ export function UsageLogsTable({ logCategory }: UsageLogsTableProps) {
|
|||||||
getFacetedRowModel: getFacetedRowModel(),
|
getFacetedRowModel: getFacetedRowModel(),
|
||||||
getFacetedUniqueValues: getFacetedUniqueValues(),
|
getFacetedUniqueValues: getFacetedUniqueValues(),
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
|
manualFiltering: true,
|
||||||
pageCount: Math.ceil((data?.total || 0) / pagination.pageSize),
|
pageCount: Math.ceil((data?.total || 0) / pagination.pageSize),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const logTypeSearchSchema = z
|
|||||||
const usageLogsSearchSchema = z.object({
|
const usageLogsSearchSchema = z.object({
|
||||||
page: z.number().optional().catch(1),
|
page: z.number().optional().catch(1),
|
||||||
pageSize: z.number().optional().catch(undefined),
|
pageSize: z.number().optional().catch(undefined),
|
||||||
type: logTypeSearchSchema,
|
type: logTypeSearchSchema.optional(),
|
||||||
filter: z.string().optional().catch(''),
|
filter: z.string().optional().catch(''),
|
||||||
model: z.string().optional().catch(''),
|
model: z.string().optional().catch(''),
|
||||||
token: z.string().optional().catch(''),
|
token: z.string().optional().catch(''),
|
||||||
|
|||||||
Reference in New Issue
Block a user