爆款开头API开发完成
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from app.services.log_config import LOG_DATE_FORMAT, LOG_DIR, is_enabled
|
||||
|
||||
MAX_LOG_FIELD_LENGTH = 20000
|
||||
MODULE_LOG_ROOT = os.path.join(os.path.dirname(LOG_DIR), "ModuleGeneration")
|
||||
|
||||
|
||||
def _safe_module_name(module: str | None) -> str:
|
||||
value = str(module or "unknown_module").strip() or "unknown_module"
|
||||
value = re.sub(r"[^a-zA-Z0-9_.-]+", "_", value)
|
||||
return value[:120] or "unknown_module"
|
||||
|
||||
|
||||
def _safe_dump_value(value: Any) -> Any:
|
||||
"""限制单字段长度,避免超长 base64 / 响应体把日志打爆。"""
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, str):
|
||||
if len(value) > MAX_LOG_FIELD_LENGTH:
|
||||
return value[:MAX_LOG_FIELD_LENGTH] + f"...<truncated:{len(value) - MAX_LOG_FIELD_LENGTH}>"
|
||||
return value
|
||||
if isinstance(value, dict):
|
||||
return {str(k): _safe_dump_value(v) for k, v in value.items()}
|
||||
if isinstance(value, list):
|
||||
return [_safe_dump_value(v) for v in value]
|
||||
return value
|
||||
|
||||
|
||||
def _append_module_log(module: str, entry: dict[str, Any]) -> None:
|
||||
if not is_enabled():
|
||||
return
|
||||
try:
|
||||
module_dir = os.path.join(MODULE_LOG_ROOT, _safe_module_name(module))
|
||||
os.makedirs(module_dir, exist_ok=True)
|
||||
today = datetime.now().strftime(LOG_DATE_FORMAT)
|
||||
log_file = os.path.join(module_dir, f"{today}.log")
|
||||
with open(log_file, "a", encoding="utf-8") as f:
|
||||
f.write(json.dumps(entry, ensure_ascii=False, default=str) + "\n")
|
||||
except Exception:
|
||||
# 日志失败绝不能影响业务主流程。
|
||||
pass
|
||||
|
||||
|
||||
def log_module_event_file(
|
||||
*,
|
||||
module: str,
|
||||
event_type: str,
|
||||
project_id: str | None = None,
|
||||
step_id: str | None = None,
|
||||
user_id: str | None = None,
|
||||
message: str | None = None,
|
||||
detail: dict[str, Any] | None = None,
|
||||
error: str | None = None,
|
||||
) -> None:
|
||||
"""记录模块流程事件到 JSONL 文件。
|
||||
|
||||
统一落盘目录:log/ModuleGeneration/{module}/YYYY-MM-DD.log
|
||||
不再写 module_generation_events 表。
|
||||
"""
|
||||
entry = {
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"log_type": "module_event",
|
||||
"module": module,
|
||||
"event_type": event_type,
|
||||
"project_id": project_id,
|
||||
"step_id": step_id,
|
||||
"user_id": user_id,
|
||||
"message": message,
|
||||
"detail": _safe_dump_value(detail or {}),
|
||||
"error": error,
|
||||
}
|
||||
_append_module_log(module, entry)
|
||||
|
||||
|
||||
def log_module_prompt_event(
|
||||
*,
|
||||
event_type: str,
|
||||
project_id: str,
|
||||
step_id: str,
|
||||
user_id: str,
|
||||
module: str,
|
||||
prompt_type: str,
|
||||
request: dict[str, Any] | None = None,
|
||||
response: dict[str, Any] | None = None,
|
||||
token_usage: dict[str, Any] | None = None,
|
||||
error: str | None = None,
|
||||
) -> None:
|
||||
"""记录模块 AI 提词请求/响应到 JSONL 文件。
|
||||
|
||||
与模块事件共用同一个服务,但按 module 分目录,方便按模块排查。
|
||||
"""
|
||||
entry = {
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"log_type": "module_prompt",
|
||||
"module": module,
|
||||
"event_type": event_type,
|
||||
"prompt_type": prompt_type,
|
||||
"project_id": project_id,
|
||||
"step_id": step_id,
|
||||
"user_id": user_id,
|
||||
"request": _safe_dump_value(request or {}),
|
||||
"response": _safe_dump_value(response or {}),
|
||||
"token_usage": _safe_dump_value(token_usage or {}),
|
||||
"error": error,
|
||||
}
|
||||
_append_module_log(module, entry)
|
||||
|
||||
|
||||
def log_module_error(
|
||||
*,
|
||||
module: str,
|
||||
event_type: str,
|
||||
project_id: str | None = None,
|
||||
step_id: str | None = None,
|
||||
user_id: str | None = None,
|
||||
message: str | None = None,
|
||||
detail: dict[str, Any] | None = None,
|
||||
error: str | None = None,
|
||||
) -> None:
|
||||
"""记录模块异常日志。"""
|
||||
entry = {
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"log_type": "module_error",
|
||||
"module": module,
|
||||
"event_type": event_type,
|
||||
"project_id": project_id,
|
||||
"step_id": step_id,
|
||||
"user_id": user_id,
|
||||
"message": message,
|
||||
"detail": _safe_dump_value(detail or {}),
|
||||
"error": error,
|
||||
}
|
||||
_append_module_log(module, entry)
|
||||
Reference in New Issue
Block a user