"""Metrics calculation for cron pool monitoring (监控指标). Calculates: - Pool utilization (busy/total) - Task backlog (pending tasks count) - Stuck rate (stuck/total) - Average task processing time - Eval completion rate """ from typing import Optional from sqlmodel import Session, select from agenteval.intelligent_eval.models import IntelligentEvalStatus from agenteval.storage.db import ( IntelligentEvalDB, IntelligentEvalTaskQueueDB, OpenClawCronPoolDB, utc_now, ) def calculate_pool_utilization(session: Session) -> float: """Calculate pool utilization (busy/total). Returns: Utilization rate (0.0 to 1.0) """ crons = session.exec(select(OpenClawCronPoolDB)).all() if not crons: return 0.0 busy = sum(1 for c in crons if c.status == "busy") return busy / len(crons) def calculate_task_backlog(session: Session) -> int: """Calculate task backlog (pending tasks count). Returns: Number of pending tasks """ pending = session.exec( select(IntelligentEvalTaskQueueDB).where(IntelligentEvalTaskQueueDB.status == "pending") ).all() return len(pending) def calculate_stuck_rate(session: Session) -> float: """Calculate stuck rate (stuck/total). Returns: Stuck rate (0.0 to 1.0) """ crons = session.exec(select(OpenClawCronPoolDB)).all() if not crons: return 0.0 stuck = sum(1 for c in crons if c.status == "stuck") return stuck / len(crons) def calculate_avg_processing_time(session: Session) -> Optional[float]: """Calculate average task processing time (in seconds). Returns: Average processing time in seconds, or None if no completed tasks """ completed_tasks = session.exec( select(IntelligentEvalTaskQueueDB).where( IntelligentEvalTaskQueueDB.status == "completed", IntelligentEvalTaskQueueDB.assigned_at.isnot(None), IntelligentEvalTaskQueueDB.completed_at.isnot(None), ) ).all() if not completed_tasks: return None total_seconds = 0 for task in completed_tasks: if task.assigned_at and task.completed_at: duration = (task.completed_at - task.assigned_at).total_seconds() total_seconds += duration return total_seconds / len(completed_tasks) def calculate_eval_completion_rate(session: Session) -> float: """Calculate evaluation completion rate. Returns: Completion rate (0.0 to 1.0) """ all_evals = session.exec(select(IntelligentEvalDB)).all() if not all_evals: return 0.0 completed = sum(1 for e in all_evals if e.status == IntelligentEvalStatus.COMPLETED.value) return completed / len(all_evals) def get_all_metrics(session: Session) -> dict: """Get all metrics. Returns: Dict with all metrics """ return { "pool_utilization": calculate_pool_utilization(session), "task_backlog": calculate_task_backlog(session), "stuck_rate": calculate_stuck_rate(session), "avg_processing_time_seconds": calculate_avg_processing_time(session), "eval_completion_rate": calculate_eval_completion_rate(session), "timestamp": utc_now().isoformat(), }