mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-09-05 15:36:45 +08:00
feat(stats): 添加 API 调用详情查看功能
- 在 keys_status 页面添加了 API 调用统计卡片(1分钟/1小时/24小时)的可点击功能。 - 点击卡片会弹出一个模态框,显示对应时间段内的详细 API 调用记录,包括时间戳、部分 API 密钥、模型名称和调用状态(成功/失败)。 - 后端新增 `/api/stats/details` API 端点,用于根据请求的时间段('1m', '1h', '24h')从数据库查询并返回调用详情。 - 新增 `stats_service.get_api_call_details` 服务函数处理数据查询和格式化逻辑。 - 前端 `keys_status.js` 添加了 fetch 调用、模态框显示/隐藏以及数据渲染逻辑。 - 为 `keys_status` 页面添加了每 60 秒自动刷新的功能。 - 优化数据库连接配置,在 `create_engine` 中添加 `pool_pre_ping=True` 以提高连接可靠性。
This commit is contained in:
@@ -66,4 +66,58 @@ async def get_api_usage_stats() -> dict:
|
||||
"calls_1h": 0,
|
||||
"calls_24h": 0,
|
||||
"calls_month": 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async def get_api_call_details(period: str) -> list[dict]:
|
||||
"""
|
||||
获取指定时间段内的 API 调用详情
|
||||
|
||||
Args:
|
||||
period: 时间段标识 ('1m', '1h', '24h')
|
||||
|
||||
Returns:
|
||||
包含调用详情的字典列表,每个字典包含 timestamp, key, model, status
|
||||
|
||||
Raises:
|
||||
ValueError: 如果 period 无效
|
||||
"""
|
||||
now = datetime.datetime.now()
|
||||
if period == '1m':
|
||||
start_time = now - datetime.timedelta(minutes=1)
|
||||
elif period == '1h':
|
||||
start_time = now - datetime.timedelta(hours=1)
|
||||
elif period == '24h':
|
||||
start_time = now - datetime.timedelta(hours=24)
|
||||
else:
|
||||
raise ValueError(f"无效的时间段标识: {period}")
|
||||
|
||||
try:
|
||||
query = select(
|
||||
RequestLog.request_time.label("timestamp"),
|
||||
RequestLog.api_key.label("key"),
|
||||
RequestLog.model_name.label("model"),
|
||||
RequestLog.status_code # We might need to map this to 'success'/'failure' later
|
||||
).where(
|
||||
RequestLog.request_time >= start_time
|
||||
).order_by(RequestLog.request_time.desc()) # Order by most recent first
|
||||
|
||||
results = await database.fetch_all(query)
|
||||
|
||||
# Convert results to list of dicts and map status_code
|
||||
details = []
|
||||
for row in results:
|
||||
status = 'success' if 200 <= row['status_code'] < 300 else 'failure'
|
||||
details.append({
|
||||
"timestamp": row['timestamp'].isoformat(), # Use ISO format for JS compatibility
|
||||
"key": row['key'],
|
||||
"model": row['model'],
|
||||
"status": status
|
||||
})
|
||||
logger.info(f"Retrieved {len(details)} API call details for period '{period}'")
|
||||
return details
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get API call details for period '{period}': {e}")
|
||||
# Re-raise the exception to be handled by the route
|
||||
raise
|
||||
Reference in New Issue
Block a user