Просмотр исходного кода

feat: 日志新增rpm和tpm数据。(close #384)

CalciumIon 1 год назад
Родитель
Сommit
c92ab3b569
3 измененных файлов с 57 добавлено и 26 удалено
  1. 21 2
      model/log.go
  2. 8 1
      relay/relay-text.go
  3. 28 23
      web/src/components/LogsTable.js

+ 21 - 2
model/log.go

@@ -7,6 +7,7 @@ import (
 	"gorm.io/gorm"
 	"one-api/common"
 	"strings"
+	"time"
 )
 
 type Log struct {
@@ -172,12 +173,18 @@ 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, count(*) rpm, sum(prompt_tokens) + sum(completion_tokens) tpm")
+	tx := DB.Table("logs").Select("sum(quota) quota")
+
+	// 为rpm和tpm创建单独的查询
+	rpmTpmQuery := DB.Table("logs").Select("count(*) rpm, sum(prompt_tokens) + sum(completion_tokens) tpm")
+
 	if username != "" {
 		tx = tx.Where("username = ?", username)
+		rpmTpmQuery = rpmTpmQuery.Where("username = ?", username)
 	}
 	if tokenName != "" {
 		tx = tx.Where("token_name = ?", tokenName)
+		rpmTpmQuery = rpmTpmQuery.Where("token_name = ?", tokenName)
 	}
 	if startTimestamp != 0 {
 		tx = tx.Where("created_at >= ?", startTimestamp)
@@ -187,11 +194,23 @@ func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelNa
 	}
 	if modelName != "" {
 		tx = tx.Where("model_name = ?", modelName)
+		rpmTpmQuery = rpmTpmQuery.Where("model_name = ?", modelName)
 	}
 	if channel != 0 {
 		tx = tx.Where("channel_id = ?", channel)
+		rpmTpmQuery = rpmTpmQuery.Where("channel_id = ?", channel)
 	}
-	tx.Where("type = ?", LogTypeConsume).Scan(&stat)
+
+	tx = tx.Where("type = ?", LogTypeConsume)
+	rpmTpmQuery = rpmTpmQuery.Where("type = ?", LogTypeConsume)
+
+	// 只统计最近60秒的rpm和tpm
+	rpmTpmQuery = rpmTpmQuery.Where("created_at >= ?", time.Now().Add(-60*time.Second).Unix())
+
+	// 执行查询
+	tx.Scan(&stat)
+	rpmTpmQuery.Scan(&stat)
+
 	return stat
 }
 

+ 8 - 1
relay/relay-text.go

@@ -286,7 +286,14 @@ func returnPreConsumedQuota(c *gin.Context, tokenId int, userQuota int, preConsu
 func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, modelName string,
 	usage *dto.Usage, ratio float64, preConsumedQuota int, userQuota int, modelRatio float64, groupRatio float64,
 	modelPrice float64, usePrice bool, extraContent string) {
-
+	if usage == nil {
+		usage = &dto.Usage{
+			PromptTokens:     relayInfo.PromptTokens,
+			CompletionTokens: 0,
+			TotalTokens:      relayInfo.PromptTokens,
+		}
+		extraContent += "  ,(可能是请求出错)"
+	}
 	useTimeSeconds := time.Now().Unix() - relayInfo.StartTime.Unix()
 	promptTokens := usage.PromptTokens
 	completionTokens := usage.CompletionTokens

+ 28 - 23
web/src/components/LogsTable.js

@@ -475,6 +475,9 @@ const LogsTable = () => {
   };
 
   const handleEyeClick = async () => {
+    if (loadingStat) {
+      return;
+    }
     setLoadingStat(true);
     if (isAdminUser) {
       await getLogStat();
@@ -596,6 +599,7 @@ const LogsTable = () => {
       .catch((reason) => {
         showError(reason);
       });
+    handleEyeClick();
   }, []);
 
   const searchLogs = async () => {
@@ -622,19 +626,17 @@ const LogsTable = () => {
       <Layout>
         <Header>
           <Spin spinning={loadingStat}>
-            <h3>
-              使用明细(总消耗额度:
-              <span
-                onClick={handleEyeClick}
-                style={{
-                  cursor: 'pointer',
-                  color: 'gray',
-                }}
-              >
-                {showStat ? renderQuota(stat.quota) : '点击查看'}
-              </span>
-              )
-            </h3>
+            <Space>
+              <Tag color='green' size='large' style={{ padding: 15 }}>
+                总消耗额度: {renderQuota(stat.quota)}
+              </Tag>
+              <Tag color='blue' size='large' style={{ padding: 15 }}>
+                RPM: {stat.rpm}
+              </Tag>
+              <Tag color='purple' size='large' style={{ padding: 15 }}>
+                TPM: {stat.tpm}
+              </Tag>
+            </Space>
           </Spin>
         </Header>
         <Form layout='horizontal' style={{ marginTop: 10 }}>
@@ -700,17 +702,19 @@ const LogsTable = () => {
                 />
               </>
             )}
+            <Button
+              label='查询'
+              type='primary'
+              htmlType='submit'
+              className='btn-margin-right'
+              onClick={refresh}
+              loading={loading}
+              style={{ marginTop: 24 }}
+            >
+              查询
+            </Button>
             <Form.Section>
-              <Button
-                label='查询'
-                type='primary'
-                htmlType='submit'
-                className='btn-margin-right'
-                onClick={refresh}
-                loading={loading}
-              >
-                查询
-              </Button>
+
             </Form.Section>
           </>
         </Form>
@@ -736,6 +740,7 @@ const LogsTable = () => {
           onChange={(value) => {
             setLogType(parseInt(value));
             loadLogs(0, pageSize, parseInt(value));
+            handleEyeClick();
           }}
         >
           <Select.Option value='0'>全部</Select.Option>