This commit is contained in:
rjb
2026-01-23 09:49:45 +08:00
parent 32ce289b3b
commit 171a6edf94
24 changed files with 7317 additions and 72 deletions

View File

@@ -1,10 +1,10 @@
"""
执行日志API
"""
from fastapi import APIRouter, Depends, Query
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional
from typing import List, Optional, Dict, Any
from datetime import datetime
from app.core.database import get_db
from app.models.execution_log import ExecutionLog
@@ -14,6 +14,10 @@ from app.models.agent import Agent
from app.api.auth import get_current_user
from app.models.user import User
from app.core.exceptions import NotFoundError
import json
import logging
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1/execution-logs", tags=["execution-logs"])
@@ -266,3 +270,153 @@ async def get_execution_performance(
for log in timeline_logs
]
}
@router.get("/executions/{execution_id}/nodes/{node_id}/data")
async def get_node_execution_data(
execution_id: str,
node_id: str,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
获取特定节点的执行数据(输入和输出)
从执行日志中提取节点的输入和输出数据
"""
# 验证执行记录是否存在
execution = db.query(Execution).filter(Execution.id == execution_id).first()
if not execution:
raise NotFoundError("执行记录", execution_id)
# 验证权限检查workflow或agent的所有权
has_permission = False
if execution.workflow_id:
workflow = db.query(Workflow).filter(Workflow.id == execution.workflow_id).first()
if workflow and workflow.user_id == current_user.id:
has_permission = True
elif execution.agent_id:
agent = db.query(Agent).filter(Agent.id == execution.agent_id).first()
if agent and (agent.user_id == current_user.id or agent.status in ["published", "running"]):
has_permission = True
if not has_permission:
raise NotFoundError("执行记录", execution_id)
# 查找节点的开始和完成日志
start_log = db.query(ExecutionLog).filter(
ExecutionLog.execution_id == execution_id,
ExecutionLog.node_id == node_id,
ExecutionLog.message.like('%开始执行%')
).order_by(ExecutionLog.timestamp.asc()).first()
complete_log = db.query(ExecutionLog).filter(
ExecutionLog.execution_id == execution_id,
ExecutionLog.node_id == node_id,
ExecutionLog.message.like('%执行完成%')
).order_by(ExecutionLog.timestamp.desc()).first()
input_data = None
output_data = None
# 从开始日志中提取输入数据
if start_log and start_log.data:
input_data = start_log.data.get('input', start_log.data)
# 从完成日志中提取输出数据
if complete_log and complete_log.data:
output_data = complete_log.data.get('output', complete_log.data)
return {
"execution_id": execution_id,
"node_id": node_id,
"input": input_data,
"output": output_data,
"start_time": start_log.timestamp.isoformat() if start_log else None,
"complete_time": complete_log.timestamp.isoformat() if complete_log else None,
"duration": complete_log.duration if complete_log else None
}
@router.get("/cache/{key:path}")
async def get_cache_value(
key: str,
current_user: User = Depends(get_current_user)
):
"""
获取缓存值(记忆数据)
从Redis或内存缓存中获取指定key的值
"""
try:
from app.core.redis_client import get_redis_client
redis_client = get_redis_client()
value = None
if redis_client:
# 从Redis获取
try:
cached_data = redis_client.get(key)
if cached_data:
value = json.loads(cached_data)
except json.JSONDecodeError:
# 如果不是JSON直接返回字符串
value = cached_data
except Exception as e:
logger.warning(f"从Redis获取缓存失败: {str(e)}")
if value is None:
# 如果Redis中没有返回空
raise HTTPException(status_code=404, detail=f"缓存键 '{key}' 不存在")
return {
"key": key,
"value": value,
"exists": True
}
except HTTPException:
raise
except Exception as e:
logger.error(f"获取缓存值失败: {str(e)}")
raise HTTPException(status_code=500, detail=f"获取缓存值失败: {str(e)}")
@router.delete("/cache/{key:path}")
async def delete_cache_value(
key: str,
current_user: User = Depends(get_current_user)
):
"""
删除缓存值(记忆数据)
从Redis或内存缓存中删除指定key的值
"""
try:
from app.core.redis_client import get_redis_client
redis_client = get_redis_client()
deleted = False
if redis_client:
# 从Redis删除
try:
result = redis_client.delete(key)
deleted = result > 0
except Exception as e:
logger.warning(f"从Redis删除缓存失败: {str(e)}")
if not deleted:
raise HTTPException(status_code=404, detail=f"缓存键 '{key}' 不存在")
return {
"key": key,
"deleted": True,
"message": "缓存已删除"
}
except HTTPException:
raise
except Exception as e:
logger.error(f"删除缓存值失败: {str(e)}")
raise HTTPException(status_code=500, detail=f"删除缓存值失败: {str(e)}")