Spaces:
Paused
Paused
Upload 3 files
Browse files- app.py +60 -6
- templates/dashboard.html +9 -2
app.py
CHANGED
|
@@ -57,6 +57,7 @@ total_tokens = {
|
|
| 57 |
|
| 58 |
# 模型调用记录
|
| 59 |
model_usage_records = [] # 每次调用详细记录
|
|
|
|
| 60 |
|
| 61 |
# 计算点信息
|
| 62 |
compute_points = {
|
|
@@ -77,7 +78,41 @@ compute_points_log = {
|
|
| 77 |
users_compute_points = []
|
| 78 |
|
| 79 |
# 记录启动时间
|
| 80 |
-
START_TIME = datetime.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
|
| 83 |
def resolve_config():
|
|
@@ -808,7 +843,12 @@ def update_model_stats(model, prompt_tokens, completion_tokens):
|
|
| 808 |
global model_usage_stats, total_tokens, model_usage_records
|
| 809 |
|
| 810 |
# 添加调用记录
|
| 811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 812 |
record = {
|
| 813 |
"model": model,
|
| 814 |
"call_time": call_time,
|
|
@@ -822,6 +862,9 @@ def update_model_stats(model, prompt_tokens, completion_tokens):
|
|
| 822 |
if len(model_usage_records) > 500:
|
| 823 |
model_usage_records.pop(0)
|
| 824 |
|
|
|
|
|
|
|
|
|
|
| 825 |
# 更新聚合统计
|
| 826 |
if model not in model_usage_stats:
|
| 827 |
model_usage_stats[model] = {
|
|
@@ -899,6 +942,9 @@ def get_compute_points():
|
|
| 899 |
used = total - left
|
| 900 |
percentage = round((used / total) * 100, 2) if total > 0 else 0
|
| 901 |
|
|
|
|
|
|
|
|
|
|
| 902 |
# 添加到用户列表
|
| 903 |
user_points = {
|
| 904 |
"user_id": i + 1, # 用户ID从1开始
|
|
@@ -906,7 +952,7 @@ def get_compute_points():
|
|
| 906 |
"total": total,
|
| 907 |
"used": used,
|
| 908 |
"percentage": percentage,
|
| 909 |
-
"last_update":
|
| 910 |
}
|
| 911 |
users_compute_points.append(user_points)
|
| 912 |
|
|
@@ -932,7 +978,7 @@ def get_compute_points():
|
|
| 932 |
compute_points["total"] = total_points
|
| 933 |
compute_points["used"] = total_points - total_left
|
| 934 |
compute_points["percentage"] = round((compute_points["used"] / compute_points["total"]) * 100, 2) if compute_points["total"] > 0 else 0
|
| 935 |
-
compute_points["last_update"] = datetime.
|
| 936 |
print(f"所有用户计算点总计: 剩余 {total_left}, 总计 {total_points}")
|
| 937 |
|
| 938 |
# 获取计算点使用日志
|
|
@@ -1007,7 +1053,9 @@ def dashboard():
|
|
| 1007 |
# 在每次访问仪表盘时更新计算点信息
|
| 1008 |
get_compute_points()
|
| 1009 |
|
| 1010 |
-
|
|
|
|
|
|
|
| 1011 |
days = uptime.days
|
| 1012 |
hours, remainder = divmod(uptime.seconds, 3600)
|
| 1013 |
minutes, seconds = divmod(remainder, 60)
|
|
@@ -1019,13 +1067,16 @@ def dashboard():
|
|
| 1019 |
else:
|
| 1020 |
uptime_str = f"{minutes}分钟 {seconds}秒"
|
| 1021 |
|
|
|
|
|
|
|
|
|
|
| 1022 |
return render_template(
|
| 1023 |
'dashboard.html',
|
| 1024 |
uptime=uptime_str,
|
| 1025 |
health_checks=health_check_counter,
|
| 1026 |
user_count=USER_NUM,
|
| 1027 |
models=sorted(list(MODELS)),
|
| 1028 |
-
year=
|
| 1029 |
model_stats=model_usage_stats,
|
| 1030 |
total_tokens=total_tokens,
|
| 1031 |
compute_points=compute_points,
|
|
@@ -1066,6 +1117,9 @@ if __name__ == "__main__":
|
|
| 1066 |
# 启动保活线程
|
| 1067 |
threading.Thread(target=keep_alive, daemon=True).start()
|
| 1068 |
|
|
|
|
|
|
|
|
|
|
| 1069 |
# 获取初始计算点信息
|
| 1070 |
get_compute_points()
|
| 1071 |
|
|
|
|
| 57 |
|
| 58 |
# 模型调用记录
|
| 59 |
model_usage_records = [] # 每次调用详细记录
|
| 60 |
+
MODEL_USAGE_RECORDS_FILE = "model_usage_records.json" # 调用记录保存文件
|
| 61 |
|
| 62 |
# 计算点信息
|
| 63 |
compute_points = {
|
|
|
|
| 78 |
users_compute_points = []
|
| 79 |
|
| 80 |
# 记录启动时间
|
| 81 |
+
START_TIME = datetime.utcnow() + timedelta(hours=8) # 北京时间
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# 自定义JSON编码器,处理datetime对象
|
| 85 |
+
class DateTimeEncoder(json.JSONEncoder):
|
| 86 |
+
def default(self, obj):
|
| 87 |
+
if isinstance(obj, datetime):
|
| 88 |
+
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
| 89 |
+
return super(DateTimeEncoder, self).default(obj)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
# 加载模型调用记录
|
| 93 |
+
def load_model_usage_records():
|
| 94 |
+
global model_usage_records
|
| 95 |
+
try:
|
| 96 |
+
if os.path.exists(MODEL_USAGE_RECORDS_FILE):
|
| 97 |
+
with open(MODEL_USAGE_RECORDS_FILE, 'r', encoding='utf-8') as f:
|
| 98 |
+
records = json.load(f)
|
| 99 |
+
if isinstance(records, list):
|
| 100 |
+
model_usage_records = records
|
| 101 |
+
print(f"成功加载 {len(model_usage_records)} 条模型调用记录")
|
| 102 |
+
else:
|
| 103 |
+
print("调用记录文件格式不正确,初始化为空列表")
|
| 104 |
+
except Exception as e:
|
| 105 |
+
print(f"加载模型调用记录失败: {e}")
|
| 106 |
+
model_usage_records = []
|
| 107 |
+
|
| 108 |
+
# 保存模型调用记录
|
| 109 |
+
def save_model_usage_records():
|
| 110 |
+
try:
|
| 111 |
+
with open(MODEL_USAGE_RECORDS_FILE, 'w', encoding='utf-8') as f:
|
| 112 |
+
json.dump(model_usage_records, f, ensure_ascii=False, indent=2, cls=DateTimeEncoder)
|
| 113 |
+
print(f"成功保存 {len(model_usage_records)} 条模型调用记录")
|
| 114 |
+
except Exception as e:
|
| 115 |
+
print(f"保存模型调用记录失败: {e}")
|
| 116 |
|
| 117 |
|
| 118 |
def resolve_config():
|
|
|
|
| 843 |
global model_usage_stats, total_tokens, model_usage_records
|
| 844 |
|
| 845 |
# 添加调用记录
|
| 846 |
+
# 获取UTC时间
|
| 847 |
+
utc_now = datetime.utcnow()
|
| 848 |
+
# 转换为北京时间 (UTC+8)
|
| 849 |
+
beijing_time = utc_now + timedelta(hours=8)
|
| 850 |
+
call_time = beijing_time.strftime('%Y-%m-%d %H:%M:%S') # 北京时间
|
| 851 |
+
|
| 852 |
record = {
|
| 853 |
"model": model,
|
| 854 |
"call_time": call_time,
|
|
|
|
| 862 |
if len(model_usage_records) > 500:
|
| 863 |
model_usage_records.pop(0)
|
| 864 |
|
| 865 |
+
# 保存调用记录到本地文件
|
| 866 |
+
save_model_usage_records()
|
| 867 |
+
|
| 868 |
# 更新聚合统计
|
| 869 |
if model not in model_usage_stats:
|
| 870 |
model_usage_stats[model] = {
|
|
|
|
| 942 |
used = total - left
|
| 943 |
percentage = round((used / total) * 100, 2) if total > 0 else 0
|
| 944 |
|
| 945 |
+
# 获取北京时间
|
| 946 |
+
beijing_now = datetime.utcnow() + timedelta(hours=8)
|
| 947 |
+
|
| 948 |
# 添加到用户列表
|
| 949 |
user_points = {
|
| 950 |
"user_id": i + 1, # 用户ID从1开始
|
|
|
|
| 952 |
"total": total,
|
| 953 |
"used": used,
|
| 954 |
"percentage": percentage,
|
| 955 |
+
"last_update": beijing_now
|
| 956 |
}
|
| 957 |
users_compute_points.append(user_points)
|
| 958 |
|
|
|
|
| 978 |
compute_points["total"] = total_points
|
| 979 |
compute_points["used"] = total_points - total_left
|
| 980 |
compute_points["percentage"] = round((compute_points["used"] / compute_points["total"]) * 100, 2) if compute_points["total"] > 0 else 0
|
| 981 |
+
compute_points["last_update"] = datetime.utcnow() + timedelta(hours=8) # 北京时间
|
| 982 |
print(f"所有用户计算点总计: 剩余 {total_left}, 总计 {total_points}")
|
| 983 |
|
| 984 |
# 获取计算点使用日志
|
|
|
|
| 1053 |
# 在每次访问仪表盘时更新计算点信息
|
| 1054 |
get_compute_points()
|
| 1055 |
|
| 1056 |
+
# 计算运行时间(使用北京时间)
|
| 1057 |
+
beijing_now = datetime.utcnow() + timedelta(hours=8)
|
| 1058 |
+
uptime = beijing_now - START_TIME
|
| 1059 |
days = uptime.days
|
| 1060 |
hours, remainder = divmod(uptime.seconds, 3600)
|
| 1061 |
minutes, seconds = divmod(remainder, 60)
|
|
|
|
| 1067 |
else:
|
| 1068 |
uptime_str = f"{minutes}分钟 {seconds}秒"
|
| 1069 |
|
| 1070 |
+
# 当前北京年份
|
| 1071 |
+
beijing_year = beijing_now.year
|
| 1072 |
+
|
| 1073 |
return render_template(
|
| 1074 |
'dashboard.html',
|
| 1075 |
uptime=uptime_str,
|
| 1076 |
health_checks=health_check_counter,
|
| 1077 |
user_count=USER_NUM,
|
| 1078 |
models=sorted(list(MODELS)),
|
| 1079 |
+
year=beijing_year,
|
| 1080 |
model_stats=model_usage_stats,
|
| 1081 |
total_tokens=total_tokens,
|
| 1082 |
compute_points=compute_points,
|
|
|
|
| 1117 |
# 启动保活线程
|
| 1118 |
threading.Thread(target=keep_alive, daemon=True).start()
|
| 1119 |
|
| 1120 |
+
# 加载历史模型调用记录
|
| 1121 |
+
load_model_usage_records()
|
| 1122 |
+
|
| 1123 |
# 获取初始计算点信息
|
| 1124 |
get_compute_points()
|
| 1125 |
|
templates/dashboard.html
CHANGED
|
@@ -479,6 +479,13 @@
|
|
| 479 |
border: 1px solid rgba(251, 189, 35, 0.3);
|
| 480 |
}
|
| 481 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 482 |
/* 媒体查询 */
|
| 483 |
@media (max-width: 768px) {
|
| 484 |
.container {
|
|
@@ -716,7 +723,7 @@
|
|
| 716 |
<table class="data-table">
|
| 717 |
<thead>
|
| 718 |
<tr>
|
| 719 |
-
<th
|
| 720 |
<th>模型</th>
|
| 721 |
<th>输入Token</th>
|
| 722 |
<th>输出Token</th>
|
|
@@ -726,7 +733,7 @@
|
|
| 726 |
<tbody>
|
| 727 |
{% for record in model_usage_records|reverse %}
|
| 728 |
<tr class="model-row {% if loop.index > 10 %}hidden-model{% endif %}">
|
| 729 |
-
<td>{{ record.call_time }}</td>
|
| 730 |
<td>{{ record.model }}</td>
|
| 731 |
<td class="token-count">{{ record.prompt_tokens|int }}</td>
|
| 732 |
<td class="token-count">{{ record.completion_tokens|int }}</td>
|
|
|
|
| 479 |
border: 1px solid rgba(251, 189, 35, 0.3);
|
| 480 |
}
|
| 481 |
|
| 482 |
+
/* 时间日期样式 */
|
| 483 |
+
.datetime {
|
| 484 |
+
font-family: 'Consolas', monospace;
|
| 485 |
+
color: rgba(230, 230, 255, 0.8);
|
| 486 |
+
font-size: 0.9rem;
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
/* 媒体查询 */
|
| 490 |
@media (max-width: 768px) {
|
| 491 |
.container {
|
|
|
|
| 723 |
<table class="data-table">
|
| 724 |
<thead>
|
| 725 |
<tr>
|
| 726 |
+
<th>调用时间 (北京时间)</th>
|
| 727 |
<th>模型</th>
|
| 728 |
<th>输入Token</th>
|
| 729 |
<th>输出Token</th>
|
|
|
|
| 733 |
<tbody>
|
| 734 |
{% for record in model_usage_records|reverse %}
|
| 735 |
<tr class="model-row {% if loop.index > 10 %}hidden-model{% endif %}">
|
| 736 |
+
<td class="datetime">{{ record.call_time }}</td>
|
| 737 |
<td>{{ record.model }}</td>
|
| 738 |
<td class="token-count">{{ record.prompt_tokens|int }}</td>
|
| 739 |
<td class="token-count">{{ record.completion_tokens|int }}</td>
|