mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-05-30 20:59:45 +08:00
feat(logs): 添加错误日志详情查看功能并优化列表显示
本次提交主要围绕错误日志模块进行了功能增强和优化:
- **后端 (`database/services.py`, `router/log_routes.py`):**
- 新增了根据日志 ID 获取单个错误日志完整详情(包括 `error_log` 和 `request_msg`)的数据库服务函数 (`get_error_log_details`) 和对应的 API 路由 (`/api/logs/errors/{log_id}/details`)。
- 修改了获取错误日志列表的 API (`/api/logs/errors`):
- 在返回数据中增加了 `error_code` 字段,以便前端展示。
- 优化了数据库查询,明确指定需要选择的列,提升性能。
- 将默认排序方式从按请求时间改为按日志 ID 降序排列,使最新的错误优先显示。
- 改进了未授权访问时的处理,返回标准的 401 HTTP 状态码。
- 更新了相关的 Pydantic 模型以匹配新的数据结构。
- **前端 (`static/js/error_logs.js`, `templates/error_logs.html`):**
- 在错误日志列表页面,将原先显示部分错误日志内容的列修改为显示 "错误码"。
- 实现了点击 "详情" 按钮时,通过异步请求新的详情 API 获取并展示完整的错误日志信息(包括详细错误日志和请求消息)的功能。
- 在详情模态框中添加了加载状态提示和获取数据失败时的错误处理逻辑。
This commit is contained in:
@@ -175,7 +175,15 @@ async def get_error_logs(
|
||||
List[Dict[str, Any]]: 错误日志列表
|
||||
"""
|
||||
try:
|
||||
query = select(ErrorLog)
|
||||
query = select(
|
||||
ErrorLog.id,
|
||||
ErrorLog.gemini_key,
|
||||
ErrorLog.model_name,
|
||||
ErrorLog.error_type,
|
||||
ErrorLog.error_log,
|
||||
ErrorLog.error_code,
|
||||
ErrorLog.request_time
|
||||
)
|
||||
|
||||
# Apply filters
|
||||
if key_search:
|
||||
@@ -192,7 +200,7 @@ async def get_error_logs(
|
||||
query = query.where(ErrorLog.request_time < end_date)
|
||||
|
||||
# Apply ordering, limit, and offset
|
||||
query = query.order_by(ErrorLog.request_time.desc()).limit(limit).offset(offset)
|
||||
query = query.order_by(ErrorLog.id.desc()).limit(limit).offset(offset)
|
||||
|
||||
result = await database.fetch_all(query)
|
||||
return [dict(row) for row in result]
|
||||
@@ -242,6 +250,37 @@ async def get_error_logs_count(
|
||||
logger.exception(f"Failed to count error logs with filters: {str(e)}") # Use exception for stack trace
|
||||
raise
|
||||
|
||||
|
||||
# 新增函数:获取单条错误日志详情
|
||||
async def get_error_log_details(log_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
根据 ID 获取单个错误日志的详细信息
|
||||
|
||||
Args:
|
||||
log_id (int): 错误日志的 ID
|
||||
|
||||
Returns:
|
||||
Optional[Dict[str, Any]]: 包含日志详细信息的字典,如果未找到则返回 None
|
||||
"""
|
||||
try:
|
||||
query = select(ErrorLog).where(ErrorLog.id == log_id)
|
||||
result = await database.fetch_one(query)
|
||||
if result:
|
||||
# 将 request_msg (JSONB) 转换为字符串以便在 API 中返回
|
||||
log_dict = dict(result)
|
||||
if 'request_msg' in log_dict and log_dict['request_msg'] is not None:
|
||||
# 确保即使是 None 或非 JSON 数据也能处理
|
||||
try:
|
||||
log_dict['request_msg'] = json.dumps(log_dict['request_msg'], ensure_ascii=False, indent=2)
|
||||
except TypeError:
|
||||
log_dict['request_msg'] = str(log_dict['request_msg']) # Fallback to string
|
||||
return log_dict
|
||||
else:
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed to get error log details for ID {log_id}: {str(e)}")
|
||||
raise
|
||||
|
||||
# 新增函数:添加请求日志
|
||||
async def add_request_log(
|
||||
model_name: Optional[str],
|
||||
|
||||
Reference in New Issue
Block a user