All checks were successful
Build and Deploy Log Center / build-and-deploy (push) Successful in 1m35s
153 lines
5.1 KiB
Python
153 lines
5.1 KiB
Python
"""
|
|
Task Manager - 与 Log Center 交互
|
|
"""
|
|
import httpx
|
|
from typing import Optional
|
|
from loguru import logger
|
|
|
|
from ..config import settings
|
|
from ..models import Bug, BugStatus, RepairReport
|
|
|
|
|
|
class TaskManager:
|
|
"""负责与 Log Center 交互"""
|
|
|
|
def __init__(self):
|
|
self.base_url = settings.log_center_url
|
|
self.client = httpx.Client(timeout=30)
|
|
|
|
def fetch_pending_bugs(self, project_id: Optional[str] = None) -> list[Bug]:
|
|
"""
|
|
获取待修复的 Bug 列表
|
|
|
|
Args:
|
|
project_id: 可选,筛选特定项目
|
|
|
|
Returns:
|
|
Bug 列表
|
|
"""
|
|
try:
|
|
params = {"status": "NEW"}
|
|
if project_id:
|
|
params["project_id"] = project_id
|
|
|
|
response = self.client.get(
|
|
f"{self.base_url}/api/v1/bugs",
|
|
params=params
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
bugs = []
|
|
|
|
for item in data.get("items", []):
|
|
# stack_trace 可能是列表或字符串
|
|
stack_trace = item.get("stack_trace")
|
|
if isinstance(stack_trace, str):
|
|
stack_trace = stack_trace.split("\n")
|
|
|
|
bug = Bug(
|
|
id=item["id"],
|
|
project_id=item["project_id"],
|
|
environment=item.get("environment", "production"),
|
|
level=item.get("level", "ERROR"),
|
|
error={
|
|
"type": item.get("error_type", "Unknown"),
|
|
"message": item.get("error_message", ""),
|
|
"file_path": item.get("file_path"),
|
|
"line_number": item.get("line_number"),
|
|
"stack_trace": stack_trace,
|
|
},
|
|
context=item.get("context"),
|
|
status=BugStatus(item.get("status", "NEW")),
|
|
retry_count=item.get("retry_count", 0),
|
|
)
|
|
bugs.append(bug)
|
|
|
|
logger.info(f"获取到 {len(bugs)} 个待修复 Bug")
|
|
return bugs
|
|
|
|
except httpx.HTTPError as e:
|
|
logger.error(f"获取 Bug 列表失败: {e}")
|
|
return []
|
|
|
|
def update_status(self, bug_id: int, status: BugStatus, message: str = "") -> bool:
|
|
"""
|
|
更新 Bug 状态
|
|
|
|
Args:
|
|
bug_id: Bug ID
|
|
status: 新状态
|
|
message: 状态说明
|
|
|
|
Returns:
|
|
是否成功
|
|
"""
|
|
try:
|
|
response = self.client.put(
|
|
f"{self.base_url}/api/v1/tasks/{bug_id}/status",
|
|
json={
|
|
"status": status.value,
|
|
"message": message
|
|
}
|
|
)
|
|
response.raise_for_status()
|
|
logger.info(f"Bug #{bug_id} 状态更新为 {status.value}")
|
|
return True
|
|
|
|
except httpx.HTTPError as e:
|
|
logger.error(f"更新状态失败: {e}")
|
|
return False
|
|
|
|
def get_bug_detail(self, bug_id: int) -> Optional[Bug]:
|
|
"""获取 Bug 详情"""
|
|
try:
|
|
response = self.client.get(f"{self.base_url}/api/v1/bugs/{bug_id}")
|
|
response.raise_for_status()
|
|
|
|
item = response.json()
|
|
|
|
# stack_trace 可能是列表或字符串
|
|
stack_trace = item.get("stack_trace")
|
|
if isinstance(stack_trace, str):
|
|
stack_trace = stack_trace.split("\n")
|
|
|
|
return Bug(
|
|
id=item["id"],
|
|
project_id=item["project_id"],
|
|
environment=item.get("environment", "production"),
|
|
level=item.get("level", "ERROR"),
|
|
error={
|
|
"type": item.get("error_type", "Unknown"),
|
|
"message": item.get("error_message", ""),
|
|
"file_path": item.get("file_path"),
|
|
"line_number": item.get("line_number"),
|
|
"stack_trace": stack_trace,
|
|
},
|
|
context=item.get("context"),
|
|
status=BugStatus(item.get("status", "NEW")),
|
|
retry_count=item.get("retry_count", 0),
|
|
)
|
|
|
|
except httpx.HTTPError as e:
|
|
logger.error(f"获取 Bug 详情失败: {e}")
|
|
return None
|
|
|
|
def upload_report(self, report: RepairReport) -> bool:
|
|
"""上传修复报告"""
|
|
try:
|
|
response = self.client.post(
|
|
f"{self.base_url}/api/v1/repair/reports",
|
|
json=report.model_dump()
|
|
)
|
|
response.raise_for_status()
|
|
logger.info(f"Bug #{report.error_log_id} 修复报告已上传")
|
|
return True
|
|
except httpx.HTTPError as e:
|
|
logger.error(f"上传修复报告失败: {e}")
|
|
return False
|
|
|
|
def close(self):
|
|
"""关闭连接"""
|
|
self.client.close()
|