更新日志的中文说明
This commit is contained in:
@@ -271,7 +271,7 @@ def _commit_source_batch(
|
||||
except Exception:
|
||||
# 文件系统回滚失败不能覆盖数据库抛出的根因,并继续清理其余对象。
|
||||
logger.exception(
|
||||
"failed to roll back data process source object task_id=%s",
|
||||
"数据处理源对象回滚失败 task_id=%s",
|
||||
task_id,
|
||||
)
|
||||
raise
|
||||
@@ -641,7 +641,7 @@ def _run_generation(
|
||||
) -> None:
|
||||
started_at = time.perf_counter()
|
||||
logger.info(
|
||||
"data process generation worker started task_id=%s generation_run_id=%s",
|
||||
"数据处理生成任务开始 task_id=%s generation_run_id=%s",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
)
|
||||
@@ -649,8 +649,7 @@ def _run_generation(
|
||||
task = store.get_task(task_id)
|
||||
if not store.generation_is_running(task_id, generation_run_id):
|
||||
logger.info(
|
||||
"data process generation worker skipped inactive run task_id=%s "
|
||||
"generation_run_id=%s",
|
||||
"数据处理生成任务跳过(非活跃运行) task_id=%s generation_run_id=%s",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
)
|
||||
@@ -740,8 +739,7 @@ def _run_generation(
|
||||
len(preview_items),
|
||||
):
|
||||
logger.info(
|
||||
"data process generation stopped before completion task_id=%s "
|
||||
"generation_run_id=%s",
|
||||
"数据处理生成任务被中止 task_id=%s generation_run_id=%s",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
)
|
||||
@@ -832,9 +830,7 @@ def _run_generation(
|
||||
"created_by": (store.get_task(task_id) or {}).get("created_by"),
|
||||
})
|
||||
logger.info(
|
||||
"data process generation completed task_id=%s generation_run_id=%s "
|
||||
"output_count=%s filtered_count=%s duplicate_count=%s error_count=%s "
|
||||
"duration_ms=%.2f",
|
||||
"数据处理生成完成 task_id=%s generation_run_id=%s output_count=%s filtered_count=%s duplicate_count=%s error_count=%s duration_ms=%.2f",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
completed.get("output_count", len(accepted)),
|
||||
@@ -845,14 +841,13 @@ def _run_generation(
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"data process generation stopped before result persistence task_id=%s "
|
||||
"generation_run_id=%s",
|
||||
"数据处理生成任务在持久化前被停止 task_id=%s generation_run_id=%s",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"data process generation failed task_id=%s generation_run_id=%s duration_ms=%.2f",
|
||||
"数据处理生成失败 task_id=%s generation_run_id=%s duration_ms=%.2f",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
(time.perf_counter() - started_at) * 1000,
|
||||
@@ -866,8 +861,7 @@ def _run_generation(
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"failed to persist data process generation failure task_id=%s "
|
||||
"generation_run_id=%s",
|
||||
"数据处理生成失败持久化异常 task_id=%s generation_run_id=%s",
|
||||
task_id,
|
||||
generation_run_id,
|
||||
)
|
||||
@@ -916,7 +910,7 @@ def create_task(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
task = store.create_task(payload.model_dump(mode="json"))
|
||||
biz_logger.info("data-process:create success", taskId=task["id"], processType=task.get("process_type", ""))
|
||||
biz_logger.info("用户创建数据处理任务成功", taskId=task["id"], processType=task.get("process_type", ""))
|
||||
return ok(task, "data process task created")
|
||||
|
||||
|
||||
@@ -943,7 +937,7 @@ def update_task(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
result = store.update_task(task_id, payload.model_dump(exclude_unset=True, mode="json"))
|
||||
biz_logger.info("data-process:update success", taskId=task_id)
|
||||
biz_logger.info("用户更新数据处理任务成功", taskId=task_id)
|
||||
return ok(result, "data process task updated")
|
||||
|
||||
|
||||
@@ -1033,7 +1027,7 @@ def _remove_repeated_storage_objects(
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"failed to roll back repeated data process source object task_id=%s",
|
||||
"数据处理源对象重复回滚失败 task_id=%s",
|
||||
task_id,
|
||||
)
|
||||
|
||||
@@ -1109,7 +1103,7 @@ def delete_task(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
store.delete_task(task_id)
|
||||
biz_logger.info("data-process:delete success", taskId=task_id)
|
||||
biz_logger.info("用户删除数据处理任务成功", taskId=task_id)
|
||||
return ok({"deleted": task_id}, "data process task deleted")
|
||||
|
||||
|
||||
@@ -1424,10 +1418,10 @@ def delete_source_file(
|
||||
except Exception:
|
||||
cleanup_pending = True
|
||||
logger.exception(
|
||||
"failed to remove data process source object after soft deletion",
|
||||
"数据处理源对象软删除后存储清理失败",
|
||||
extra={"task_id": task_id, "source_file_id": file_id},
|
||||
)
|
||||
biz_logger.info("data-process:delete-source-file success", taskId=task_id, fileId=file_id, storageCleanupPending=cleanup_pending)
|
||||
biz_logger.info("用户删除数据处理源文件成功", taskId=task_id, fileId=file_id, storageCleanupPending=cleanup_pending)
|
||||
return ok(
|
||||
{"deleted": file_id, "storage_cleanup_pending": cleanup_pending},
|
||||
"source file removed",
|
||||
@@ -1700,7 +1694,7 @@ def _prepare_preview_items(
|
||||
extracted_text = "\n\n".join(page.text for page in pages if page.text)
|
||||
if extracted_text != str(source.get("content") or ""):
|
||||
logger.warning(
|
||||
"skip PDF document noise detection because stored offsets differ for %s",
|
||||
"跳过PDF文档噪声检测(存储偏移量不一致) source_id=%s",
|
||||
source["id"],
|
||||
)
|
||||
continue
|
||||
@@ -1723,7 +1717,7 @@ def _run_preview(
|
||||
|
||||
started_at = time.perf_counter()
|
||||
logger.info(
|
||||
"data process preview started task_id=%s preview_run_id=%s total_files=%s",
|
||||
"数据处理预览开始 task_id=%s preview_run_id=%s total_files=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
len(source_file_ids),
|
||||
@@ -1732,7 +1726,7 @@ def _run_preview(
|
||||
is_unstructured = store.get_task(task_id).get("process_type") == "unstructured"
|
||||
if not store.mark_preview_running(task_id, preview_run_id):
|
||||
logger.info(
|
||||
"data process preview skipped inactive run task_id=%s preview_run_id=%s",
|
||||
"数据处理预览跳过(非活跃运行) task_id=%s preview_run_id=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
)
|
||||
@@ -1742,8 +1736,7 @@ def _run_preview(
|
||||
for completed_files, source_file_id in enumerate(source_file_ids, start=1):
|
||||
if not store.preview_is_running(task_id, preview_run_id):
|
||||
logger.info(
|
||||
"data process preview cancelled task_id=%s preview_run_id=%s "
|
||||
"completed_files=%s total_files=%s",
|
||||
"数据处理预览被取消 task_id=%s preview_run_id=%s completed_files=%s total_files=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
completed_files - 1,
|
||||
@@ -1774,8 +1767,7 @@ def _run_preview(
|
||||
total_files,
|
||||
):
|
||||
logger.info(
|
||||
"data process preview stopped before progress update task_id=%s "
|
||||
"preview_run_id=%s completed_files=%s total_files=%s",
|
||||
"数据处理预览在进度更新前被停止 task_id=%s preview_run_id=%s completed_files=%s total_files=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
completed_files,
|
||||
@@ -1784,8 +1776,7 @@ def _run_preview(
|
||||
return
|
||||
if store.complete_preview(task_id, preview_run_id):
|
||||
logger.info(
|
||||
"data process preview completed task_id=%s preview_run_id=%s "
|
||||
"total_files=%s total_items=%s duration_ms=%.2f",
|
||||
"数据处理预览完成 task_id=%s preview_run_id=%s total_files=%s total_items=%s duration_ms=%.2f",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
total_files,
|
||||
@@ -1794,14 +1785,13 @@ def _run_preview(
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"data process preview completion ignored for inactive run task_id=%s "
|
||||
"preview_run_id=%s",
|
||||
"数据处理预览完成但运行已失效 task_id=%s preview_run_id=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"data process preview failed task_id=%s preview_run_id=%s duration_ms=%.2f",
|
||||
"数据处理预览失败 task_id=%s preview_run_id=%s duration_ms=%.2f",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
(time.perf_counter() - started_at) * 1000,
|
||||
@@ -1815,8 +1805,7 @@ def _run_preview(
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"failed to persist data process preview failure task_id=%s "
|
||||
"preview_run_id=%s",
|
||||
"数据处理预览失败持久化异常 task_id=%s preview_run_id=%s",
|
||||
task_id,
|
||||
preview_run_id,
|
||||
)
|
||||
@@ -2026,7 +2015,7 @@ def stop(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
store.stop_task(task_id)
|
||||
biz_logger.info("data-process:stop success", taskId=task_id)
|
||||
biz_logger.info("用户停止数据处理任务成功", taskId=task_id)
|
||||
return ok(store.progress(task_id), "data process task stopped")
|
||||
|
||||
|
||||
@@ -2069,7 +2058,7 @@ def confirm_results(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
result = store.confirm_results(task_id)
|
||||
biz_logger.info("data-process:confirm-results success", taskId=task_id)
|
||||
biz_logger.info("用户确认数据处理结果成功", taskId=task_id)
|
||||
return ok(result, "data process results confirmed")
|
||||
|
||||
|
||||
@@ -2419,8 +2408,7 @@ def regenerate_results_batch(
|
||||
}))
|
||||
|
||||
logger.info(
|
||||
"data process result batch regeneration started batch_id=%s task_id=%s "
|
||||
"requested=%s prepared=%s concurrency=%s",
|
||||
"数据处理结果批量重新生成开始 batch_id=%s task_id=%s requested=%s prepared=%s concurrency=%s",
|
||||
batch_id,
|
||||
task_id,
|
||||
len(payload.items),
|
||||
@@ -2488,8 +2476,7 @@ def regenerate_results_batch(
|
||||
except Exception as exc: # pragma: no cover - defensive boundary
|
||||
outcome = "internal_error"
|
||||
logger.exception(
|
||||
"data process result batch regeneration crashed "
|
||||
"batch_id=%s task_id=%s result_id=%s",
|
||||
"数据处理结果批量重新生成崩溃 batch_id=%s task_id=%s result_id=%s",
|
||||
batch_id,
|
||||
task_id,
|
||||
result_id,
|
||||
@@ -2500,8 +2487,7 @@ def regenerate_results_batch(
|
||||
"message": _safe_regeneration_error(exc),
|
||||
}))
|
||||
logger.info(
|
||||
"data process result batch item finished batch_id=%s task_id=%s "
|
||||
"result_id=%s outcome=%s duration_ms=%.2f",
|
||||
"数据处理结果批量项完成 batch_id=%s task_id=%s result_id=%s outcome=%s duration_ms=%.2f",
|
||||
batch_id,
|
||||
task_id,
|
||||
result_id,
|
||||
@@ -2521,8 +2507,7 @@ def regenerate_results_batch(
|
||||
)
|
||||
duration_ms = (time.perf_counter() - started_at) * 1000
|
||||
logger.info(
|
||||
"data process result batch regeneration completed batch_id=%s task_id=%s "
|
||||
"succeeded=%s failed=%s remaining_invalid=%s duration_ms=%.2f",
|
||||
"数据处理结果批量重新生成完成 batch_id=%s task_id=%s succeeded=%s failed=%s remaining_invalid=%s duration_ms=%.2f",
|
||||
batch_id,
|
||||
task_id,
|
||||
len(success_items),
|
||||
@@ -2569,8 +2554,7 @@ def evaluate_results_batch(
|
||||
evaluation_model = store.get_generation_model(str(model_id))
|
||||
except NotFoundError:
|
||||
logger.warning(
|
||||
"data process evaluation model unavailable, judge layer "
|
||||
"skipped task_id=%s model_id=%s",
|
||||
"数据处理评测模型不可用,跳过评测层 task_id=%s model_id=%s",
|
||||
task_id,
|
||||
model_id,
|
||||
)
|
||||
@@ -2618,8 +2602,7 @@ def evaluate_results_batch(
|
||||
}))
|
||||
|
||||
logger.info(
|
||||
"data process result batch evaluation started batch_id=%s task_id=%s "
|
||||
"requested=%s prepared=%s judge_enabled=%s",
|
||||
"数据处理结果批量评测开始 batch_id=%s task_id=%s requested=%s prepared=%s judge_enabled=%s",
|
||||
batch_id,
|
||||
task_id,
|
||||
len(payload.items),
|
||||
@@ -2636,8 +2619,7 @@ def evaluate_results_batch(
|
||||
semantic_embedding_model()
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"data process semantic embedding unavailable, semantic layer "
|
||||
"will be skipped batch_id=%s",
|
||||
"数据处理语义嵌入模型不可用,语义层将跳过 batch_id=%s",
|
||||
batch_id,
|
||||
)
|
||||
request_timeout = _result_regeneration_timeout(config)
|
||||
@@ -2690,8 +2672,7 @@ def evaluate_results_batch(
|
||||
"message": _safe_regeneration_error(exc),
|
||||
}))
|
||||
logger.info(
|
||||
"data process result batch evaluation item finished "
|
||||
"batch_id=%s task_id=%s result_id=%s outcome=%s duration_ms=%.2f",
|
||||
"数据处理结果批量评测项完成 batch_id=%s task_id=%s result_id=%s outcome=%s duration_ms=%.2f",
|
||||
batch_id,
|
||||
task_id,
|
||||
result_id,
|
||||
@@ -2703,8 +2684,7 @@ def evaluate_results_batch(
|
||||
failure_items = [item for _, item in sorted(failures, key=lambda pair: pair[0])]
|
||||
duration_ms = (time.perf_counter() - started_at) * 1000
|
||||
logger.info(
|
||||
"data process result batch evaluation completed batch_id=%s task_id=%s "
|
||||
"succeeded=%s failed=%s duration_ms=%.2f",
|
||||
"数据处理结果批量评测完成 batch_id=%s task_id=%s succeeded=%s failed=%s duration_ms=%.2f",
|
||||
batch_id,
|
||||
task_id,
|
||||
len(success_items),
|
||||
@@ -2760,8 +2740,7 @@ def regenerate_result(
|
||||
)
|
||||
except _ResultRegenerationFailed as exc:
|
||||
logger.warning(
|
||||
"data process result regeneration failed task_id=%s result_id=%s "
|
||||
"duration_ms=%.2f reason=%s",
|
||||
"数据处理结果重新生成失败 task_id=%s result_id=%s duration_ms=%.2f reason=%s",
|
||||
task_id,
|
||||
result_id,
|
||||
(time.perf_counter() - started_at) * 1000,
|
||||
@@ -2769,7 +2748,7 @@ def regenerate_result(
|
||||
)
|
||||
raise
|
||||
logger.info(
|
||||
"data process result regenerated task_id=%s result_id=%s duration_ms=%.2f",
|
||||
"数据处理结果重新生成完成 task_id=%s result_id=%s duration_ms=%.2f",
|
||||
task_id,
|
||||
result_id,
|
||||
(time.perf_counter() - started_at) * 1000,
|
||||
@@ -2785,6 +2764,6 @@ def publish(
|
||||
) -> dict[str, Any]:
|
||||
with api_errors():
|
||||
result = store.publish(task_id, payload.model_dump(mode="json"))
|
||||
biz_logger.info("data-process:publish success", taskId=task_id, datasetId=result.get("dataset_id", ""))
|
||||
biz_logger.info("用户发布数据处理任务成功", taskId=task_id, datasetId=result.get("dataset_id", ""))
|
||||
message = "dataset published" if result["created"] else "dataset already published"
|
||||
return ok(result, message)
|
||||
|
||||
@@ -457,9 +457,9 @@ def setup_request_logging(app: FastAPI) -> None:
|
||||
elif response.status_code >= 400:
|
||||
log_method = logger.warning
|
||||
|
||||
# 结构化访问日志
|
||||
# 结构化访问日志(中文 message,方便直接阅读)
|
||||
log_method(
|
||||
"request completed",
|
||||
f"HTTP请求 {request.method} {request.url.path} → {response.status_code}(耗时{round(elapsed_ms, 2)}ms)",
|
||||
extra={
|
||||
"request_method": request.method,
|
||||
"request_path": request.url.path,
|
||||
@@ -497,7 +497,7 @@ def setup_request_logging(app: FastAPI) -> None:
|
||||
except Exception:
|
||||
elapsed_ms = (time.perf_counter() - started_at) * 1000
|
||||
logger.error(
|
||||
"request failed",
|
||||
f"HTTP请求异常 {request.method} {request.url.path}(耗时{round(elapsed_ms, 2)}ms)— 服务内部错误",
|
||||
extra={
|
||||
"request_method": request.method,
|
||||
"request_path": request.url.path,
|
||||
|
||||
@@ -77,6 +77,92 @@ class OpStatus:
|
||||
FAILURE = "failure"
|
||||
|
||||
|
||||
# ==================== 中文映射表(让日志 message 直接可读)====================
|
||||
|
||||
MODULE_CN: dict[str, str] = {
|
||||
"fine-tune": "模型训练",
|
||||
"model-eval": "模型评测",
|
||||
"model-inference": "模型推理",
|
||||
"model-manage": "模型管理",
|
||||
"dataset": "数据集",
|
||||
"data-process": "数据处理",
|
||||
"data-convert": "数据转换",
|
||||
"compute": "算力节点",
|
||||
"system": "系统",
|
||||
}
|
||||
|
||||
ACTION_CN: dict[str, str] = {
|
||||
"create": "创建",
|
||||
"update": "更新",
|
||||
"delete": "删除",
|
||||
"start": "启动",
|
||||
"stop": "停止",
|
||||
"upload": "上传",
|
||||
"download": "下载",
|
||||
"convert": "转换",
|
||||
"merge": "合并",
|
||||
"import": "导入",
|
||||
"login": "登录",
|
||||
"logout": "退出登录",
|
||||
"publish": "发布",
|
||||
"retry": "重试",
|
||||
"request": "请求",
|
||||
}
|
||||
|
||||
TARGET_TYPE_CN: dict[str, str] = {
|
||||
"fine_tune": "训练任务",
|
||||
"eval": "评测任务",
|
||||
"inference": "推理任务",
|
||||
"model": "模型",
|
||||
"trained_model": "训练产出模型",
|
||||
"dataset": "数据集",
|
||||
"dataset_version": "数据集版本",
|
||||
"data_process_task": "数据处理任务",
|
||||
"user": "用户",
|
||||
"api": "接口",
|
||||
}
|
||||
|
||||
|
||||
def _build_cn_message(
|
||||
module: str,
|
||||
action: str,
|
||||
target_type: str,
|
||||
target_name: str | None,
|
||||
target_id: str | None,
|
||||
status: str,
|
||||
username: str | None,
|
||||
error_type: str,
|
||||
error_message: str,
|
||||
) -> str:
|
||||
"""构建中文人类可读的日志消息,格式:[用户] 对 [模块] 执行了 [动作],结果:成功/失败"""
|
||||
user_part = f"用户[{username}]" if username else "系统"
|
||||
module_cn = MODULE_CN.get(module, module)
|
||||
action_cn = ACTION_CN.get(action, action)
|
||||
target_cn = TARGET_TYPE_CN.get(target_type, target_type or "")
|
||||
target_label = target_name or target_id or ""
|
||||
|
||||
# 拼接操作对象描述
|
||||
if target_cn and target_label:
|
||||
target_part = f"{target_cn}「{target_label}」"
|
||||
elif target_cn:
|
||||
target_part = target_cn
|
||||
elif target_label:
|
||||
target_part = f"「{target_label}」"
|
||||
else:
|
||||
target_part = ""
|
||||
|
||||
if status == OpStatus.SUCCESS:
|
||||
result = "成功"
|
||||
msg = f"{user_part} {action_cn}{module_cn}{target_part},结果:成功"
|
||||
else:
|
||||
result = "失败"
|
||||
err_brief = error_message[:120] if error_message else ""
|
||||
err_part = f"({error_type}: {err_brief})" if error_type and err_brief else f"({error_type})" if error_type else ""
|
||||
msg = f"{user_part} {action_cn}{module_cn}{target_part},结果:失败{err_part}"
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def op_log(
|
||||
module: str,
|
||||
action: str,
|
||||
@@ -354,6 +440,12 @@ def _write_log(
|
||||
req_path = request.url.path
|
||||
|
||||
# ---- 写文件日志(app-biz)----
|
||||
cn_msg = _build_cn_message(
|
||||
module=module, action=action, target_type=target_type,
|
||||
target_name=target_name, target_id=target_id, status=status,
|
||||
username=username, error_type=error_type, error_message=error_message,
|
||||
)
|
||||
|
||||
log_fields = {
|
||||
"bizModule": module,
|
||||
"action": action,
|
||||
@@ -364,6 +456,10 @@ def _write_log(
|
||||
"durationMs": round(duration_ms, 2),
|
||||
"username": username or "",
|
||||
}
|
||||
if req_method:
|
||||
log_fields["requestMethod"] = req_method
|
||||
if req_path:
|
||||
log_fields["requestPath"] = req_path
|
||||
if detail:
|
||||
log_fields["detail"] = detail[:500]
|
||||
if error_message:
|
||||
@@ -372,9 +468,9 @@ def _write_log(
|
||||
log_fields["errorType"] = error_type
|
||||
|
||||
if status == OpStatus.SUCCESS:
|
||||
biz_logger.info(f"{module}:{action} {status} - {target_name or target_id or ''}", **log_fields)
|
||||
biz_logger.info(cn_msg, **log_fields)
|
||||
elif status == OpStatus.FAILURE:
|
||||
biz_logger.error(f"{module}:{action} {status} - {target_name or target_id or ''} - {error_type}: {error_message[:200]}", **log_fields)
|
||||
biz_logger.error(cn_msg, **log_fields)
|
||||
|
||||
# ---- 写数据库 ----
|
||||
try:
|
||||
|
||||
@@ -13,21 +13,21 @@ logger = get_logger(__name__)
|
||||
async def run_compute_poller() -> None:
|
||||
settings = get_settings()
|
||||
if settings.compute_mode == "simulator" or settings.compute_status_sync_mode != "polling":
|
||||
logger.info("compute poller disabled", extra={"compute_mode": settings.compute_mode})
|
||||
logger.info("计算轮询已禁用", extra={"compute_mode": settings.compute_mode})
|
||||
return
|
||||
|
||||
interval = max(3, settings.compute_poll_interval_seconds)
|
||||
logger.info("compute poller started", extra={"interval_seconds": interval})
|
||||
logger.info("计算轮询已启动", extra={"interval_seconds": interval})
|
||||
while True:
|
||||
try:
|
||||
result = await poll_compute_jobs_once()
|
||||
if result["failed"]:
|
||||
logger.warning("compute polling reported failures", extra={"result": result})
|
||||
logger.warning("计算轮询检测到失败任务", extra={"result": result})
|
||||
elif result["synced"]:
|
||||
logger.debug("compute jobs synchronized", extra={"result": result})
|
||||
logger.debug("计算任务状态已同步", extra={"result": result})
|
||||
except asyncio.CancelledError:
|
||||
logger.info("compute poller stopped")
|
||||
logger.info("计算轮询已停止")
|
||||
raise
|
||||
except Exception as exc: # noqa: BLE001 - keep background polling alive
|
||||
logger.exception("compute poller failed", extra={"error": str(exc)})
|
||||
logger.exception("计算轮询执行失败", extra={"error": str(exc)})
|
||||
await asyncio.sleep(interval)
|
||||
|
||||
266
backend/test_results.json
Normal file
266
backend/test_results.json
Normal file
@@ -0,0 +1,266 @@
|
||||
[
|
||||
{
|
||||
"name": "health",
|
||||
"method": "GET",
|
||||
"url": "/health",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(4 keys)"
|
||||
},
|
||||
{
|
||||
"name": "system-info",
|
||||
"method": "GET",
|
||||
"url": "/system-info",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(7 keys)"
|
||||
},
|
||||
{
|
||||
"name": "me",
|
||||
"method": "GET",
|
||||
"url": "/me",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(9 keys)"
|
||||
},
|
||||
{
|
||||
"name": "dashboard/overview",
|
||||
"method": "GET",
|
||||
"url": "/dashboard/overview",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(6 keys)"
|
||||
},
|
||||
{
|
||||
"name": "dashboard/stats",
|
||||
"method": "GET",
|
||||
"url": "/dashboard/stats",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(9 keys)"
|
||||
},
|
||||
{
|
||||
"name": "users-list",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "9 items"
|
||||
},
|
||||
{
|
||||
"name": "users-create",
|
||||
"method": "POST",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(9 keys)"
|
||||
},
|
||||
{
|
||||
"name": "users-change-password",
|
||||
"method": "POST",
|
||||
"url": "/users/me/password",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "model-manage-list",
|
||||
"method": "GET",
|
||||
"url": "/model-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "5 items"
|
||||
},
|
||||
{
|
||||
"name": "model-manage-local",
|
||||
"method": "GET",
|
||||
"url": "/model-manage/local-models",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "model-manage-trained",
|
||||
"method": "GET",
|
||||
"url": "/model-manage/trained-models",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "model-manage-export-jobs",
|
||||
"method": "GET",
|
||||
"url": "/model-manage/export-jobs",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "11 items"
|
||||
},
|
||||
{
|
||||
"name": "model-manage-create",
|
||||
"method": "POST",
|
||||
"url": "/model-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "dataset-list",
|
||||
"method": "GET",
|
||||
"url": "/dataset-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "29 items"
|
||||
},
|
||||
{
|
||||
"name": "dataset-create",
|
||||
"method": "POST",
|
||||
"url": "/dataset-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "fine-tune-list",
|
||||
"method": "GET",
|
||||
"url": "/fine-tune",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "9 items"
|
||||
},
|
||||
{
|
||||
"name": "fine-tune-check-name",
|
||||
"method": "GET",
|
||||
"url": "/fine-tune/check-name?name=test_task",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "fine-tune-preflight",
|
||||
"method": "POST",
|
||||
"url": "/fine-tune/preflight",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(4 keys)"
|
||||
},
|
||||
{
|
||||
"name": "model-eval-list",
|
||||
"method": "GET",
|
||||
"url": "/model-eval",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "4 items"
|
||||
},
|
||||
{
|
||||
"name": "dimension-list",
|
||||
"method": "GET",
|
||||
"url": "/dimension",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "18 items"
|
||||
},
|
||||
{
|
||||
"name": "model-compare-list",
|
||||
"method": "GET",
|
||||
"url": "/model-compare",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "6 items"
|
||||
},
|
||||
{
|
||||
"name": "model-chat-local-status",
|
||||
"method": "GET",
|
||||
"url": "/model-chat/local/status",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(8 keys)"
|
||||
},
|
||||
{
|
||||
"name": "data-process-list",
|
||||
"method": "GET",
|
||||
"url": "/data-process",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(4 keys)"
|
||||
},
|
||||
{
|
||||
"name": "compute-nodes",
|
||||
"method": "GET",
|
||||
"url": "/compute/nodes",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "2 items"
|
||||
},
|
||||
{
|
||||
"name": "compute-gpus",
|
||||
"method": "GET",
|
||||
"url": "/compute/gpus",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "2 items"
|
||||
},
|
||||
{
|
||||
"name": "compute-queue",
|
||||
"method": "GET",
|
||||
"url": "/compute/queue",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "0 items"
|
||||
},
|
||||
{
|
||||
"name": "log-files",
|
||||
"method": "GET",
|
||||
"url": "/log-files",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "2 items"
|
||||
},
|
||||
{
|
||||
"name": "training-log-files",
|
||||
"method": "GET",
|
||||
"url": "/training-log-files",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "9 items"
|
||||
},
|
||||
{
|
||||
"name": "web-log",
|
||||
"method": "POST",
|
||||
"url": "/web-log",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(3 keys)"
|
||||
},
|
||||
{
|
||||
"name": "data-convert-list",
|
||||
"method": "GET",
|
||||
"url": "/data-convert",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(2 keys)"
|
||||
},
|
||||
{
|
||||
"name": "error-404",
|
||||
"method": "GET",
|
||||
"url": "/nonexistent-endpoint",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-unauthorized",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "10 items"
|
||||
},
|
||||
{
|
||||
"name": "viewer-login",
|
||||
"method": "POST",
|
||||
"url": "/login",
|
||||
"status": "SKIP",
|
||||
"message": "viewer user not found",
|
||||
"data_desc": "-"
|
||||
}
|
||||
]
|
||||
258
backend/test_results_advanced.json
Normal file
258
backend/test_results_advanced.json
Normal file
@@ -0,0 +1,258 @@
|
||||
[
|
||||
{
|
||||
"name": "crud-model-create",
|
||||
"method": "POST",
|
||||
"url": "/model-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-model-get-by-id",
|
||||
"method": "GET",
|
||||
"url": "/model-manage/m_dcebe627d644",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-model-update",
|
||||
"method": "PUT",
|
||||
"url": "/model-manage/m_dcebe627d644",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-model-purpose",
|
||||
"method": "PUT",
|
||||
"url": "/model-manage/m_dcebe627d644/purpose",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-model-delete",
|
||||
"method": "DELETE",
|
||||
"url": "/model-manage/m_dcebe627d644",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dataset-create",
|
||||
"method": "POST",
|
||||
"url": "/dataset-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dataset-get-by-id",
|
||||
"method": "GET",
|
||||
"url": "/dataset-manage/ds_b8dd915d5e09",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(28 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dataset-update",
|
||||
"method": "PUT",
|
||||
"url": "/dataset-manage/ds_b8dd915d5e09",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(27 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dataset-delete",
|
||||
"method": "DELETE",
|
||||
"url": "/dataset-manage/ds_b8dd915d5e09",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-user-create",
|
||||
"method": "POST",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(9 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-user-list",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "11 items"
|
||||
},
|
||||
{
|
||||
"name": "crud-user-update",
|
||||
"method": "PUT",
|
||||
"url": "/users/u_eb94ee60769e",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(9 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-user-reset-pwd",
|
||||
"method": "POST",
|
||||
"url": "/users/u_eb94ee60769e/reset-password",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-user-delete",
|
||||
"method": "DELETE",
|
||||
"url": "/users/u_eb94ee60769e",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(2 keys)"
|
||||
},
|
||||
{
|
||||
"name": "error-invalid-model-id",
|
||||
"method": "GET",
|
||||
"url": "/model-manage/nonexistent_id_12345",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-invalid-dataset-id",
|
||||
"method": "GET",
|
||||
"url": "/dataset-manage/nonexistent_id_12345",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-invalid-finetune-id",
|
||||
"method": "GET",
|
||||
"url": "/fine-tune/nonexistent_id_12345",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-invalid-eval-id",
|
||||
"method": "GET",
|
||||
"url": "/model-eval/nonexistent_id_12345",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-duplicate-login",
|
||||
"method": "POST",
|
||||
"url": "/login",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "error-missing-fields",
|
||||
"method": "POST",
|
||||
"url": "/model-manage",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(17 keys)"
|
||||
},
|
||||
{
|
||||
"name": "auth-no-token-users",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "10 items"
|
||||
},
|
||||
{
|
||||
"name": "auth-no-token-finetune",
|
||||
"method": "GET",
|
||||
"url": "/fine-tune",
|
||||
"status": "FAIL(code=-1)",
|
||||
"message": "",
|
||||
"data_desc": "null"
|
||||
},
|
||||
{
|
||||
"name": "auth-invalid-token",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "10 items"
|
||||
},
|
||||
{
|
||||
"name": "auth-empty-token",
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "10 items"
|
||||
},
|
||||
{
|
||||
"name": "crud-dimension-create",
|
||||
"method": "POST",
|
||||
"url": "/dimension",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(6 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dimension-get",
|
||||
"method": "GET",
|
||||
"url": "/dimension/dim_12124ed44bbe",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(6 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dimension-update",
|
||||
"method": "PUT",
|
||||
"url": "/dimension/dim_12124ed44bbe",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(6 keys)"
|
||||
},
|
||||
{
|
||||
"name": "crud-dimension-delete",
|
||||
"method": "DELETE",
|
||||
"url": "/dimension/dim_12124ed44bbe",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(1 keys)"
|
||||
},
|
||||
{
|
||||
"name": "compute-nodes-detail",
|
||||
"method": "GET",
|
||||
"url": "/compute/nodes",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "2 items"
|
||||
},
|
||||
{
|
||||
"name": "compute-nodes-list2",
|
||||
"method": "GET",
|
||||
"url": "/compute/nodes",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "2 items"
|
||||
},
|
||||
{
|
||||
"name": "compute-node-replicas",
|
||||
"method": "GET",
|
||||
"url": "/compute/nodes/node_1499a71b4871/replicas",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "9 items"
|
||||
},
|
||||
{
|
||||
"name": "compute-node-engines",
|
||||
"method": "GET",
|
||||
"url": "/compute/nodes/node_1499a71b4871/engines",
|
||||
"status": "PASS",
|
||||
"message": "ok",
|
||||
"data_desc": "obj(2 keys)"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user