from __future__ import annotations from typing import Any from urllib.parse import urlsplit, urlunsplit from app.models.chat_generation_task import ChatGenerationTask from app.models.generation_record import GenerationRecord from app.services.operation_log_service import log_operation_event def _sanitize_url(value: Any) -> Any: if not isinstance(value, str) or not value.startswith(("http://", "https://")): return value parts = urlsplit(value) return urlunsplit((parts.scheme, parts.netloc, parts.path, "", "")) def _sanitize_detail(value: Any) -> Any: if isinstance(value, dict): result: dict[str, Any] = {} for key, item in value.items(): key_text = str(key).lower() if key_text in {"authorization", "api_key", "volc_api_key"}: result[key] = "***" elif "url" in key_text: result[key] = _sanitize_url(item) else: result[key] = _sanitize_detail(item) return result if isinstance(value, list): return [_sanitize_detail(item) for item in value] return value def _owner_context(task: Any | None, upscale_task: Any | None) -> dict[str, Any]: if isinstance(task, ChatGenerationTask): return { "owner_type": "chat_generation_task", "owner_id": task.id, "chat_generation_task_id": task.id, "generation_record_id": None, "project_id": None, "generation_mode": task.generation_mode, } if isinstance(task, GenerationRecord): return { "owner_type": "generation_record", "owner_id": task.id, "chat_generation_task_id": None, "generation_record_id": task.id, "project_id": task.project_id, "generation_mode": None, } chat_task_id = getattr(upscale_task, "chat_generation_task_id", None) if upscale_task else None generation_record_id = getattr(upscale_task, "generation_record_id", None) if upscale_task else None return { "owner_type": "chat_generation_task" if chat_task_id else "generation_record" if generation_record_id else None, "owner_id": chat_task_id or generation_record_id, "chat_generation_task_id": chat_task_id, "generation_record_id": generation_record_id, "project_id": None, "generation_mode": None, } def log_video_upscale_event( *, event_type: str, event_status: str = "success", task: Any | None = None, upscale_task: Any | None = None, remote_request_id: str | None = None, message: str | None = None, detail: dict[str, Any] | None = None, error: str | None = None, ) -> None: """统一复用 operation_log_service 写入视频超分步骤日志。""" final_detail = _owner_context(task, upscale_task) final_detail.update(_sanitize_detail(dict(detail or {}))) if upscale_task is not None: final_detail.update( { "upscale_task_id": getattr(upscale_task, "id", None), "processor_key": getattr(upscale_task, "processor_key", None), "upscale_status": getattr(upscale_task, "status", None), "upscale_stage": getattr(upscale_task, "stage", None), "attempt_count": getattr(upscale_task, "attempt_count", None), "failure_count": getattr(upscale_task, "failure_count", None), "provider_task_id": getattr(upscale_task, "provider_task_id", None), "input_source_type": getattr(upscale_task, "input_source_type", None), "target_width": getattr(upscale_task, "target_width", None), "target_height": getattr(upscale_task, "target_height", None), } ) owner_id = final_detail.get("owner_id") log_operation_event( domain="video_upscale", event_type=event_type, event_status=event_status, source="service", user_id=getattr(task, "user_id", None) if task is not None else None, group_id=getattr(task, "parent_task_id", None) if task is not None else None, task_id=owner_id, remote_request_id=remote_request_id, message=message, detail=final_detail, error=error, )