Download app/admin/stats.py from bg5/zai: direct link, hf CLI and curl.
- Browser
- Download file 6.73 kB
-
https://huggingface.co/spaces/bg5/zai/resolve/main/app/admin/stats.py
- Command line
-
hf download hf://spaces/bg5/zai/app/admin/stats.py
-
curl -L -o stats.py https://huggingface.co/spaces/bg5/zai/resolve/main/app/admin/stats.py
6.73 kB
| """管理后台统计聚合辅助函数。""" | |
| from __future__ import annotations | |
| import os | |
| import time | |
| from typing import Any, Dict, Optional | |
| try: | |
| import psutil | |
| except ImportError: | |
| psutil = None | |
| from app.services.request_log_dao import RequestLogDAO, get_request_log_dao | |
| from app.services.token_dao import TokenDAO, get_token_dao | |
| from app.utils.format import format_compact_number | |
| from app.utils.token_pool import TokenPool, get_token_pool | |
| _TOKEN_POOL_SENTINEL = object() | |
| DEFAULT_TREND_WINDOW = "7d" | |
| TREND_WINDOW_OPTIONS = ( | |
| {"key": "24h", "label": "24 小时"}, | |
| {"key": "7d", "label": "7 天"}, | |
| {"key": "30d", "label": "30 天"}, | |
| ) | |
| def _coerce_int(value: Any) -> int: | |
| """将数据库聚合结果安全转换为整数。""" | |
| return int(value or 0) | |
| def calculate_success_rate( | |
| successful_requests: int, | |
| total_requests: int, | |
| ) -> float: | |
| """计算成功率百分比。""" | |
| if total_requests <= 0: | |
| return 0.0 | |
| return round(successful_requests / total_requests * 100, 1) | |
| def normalize_trend_window(value: Any) -> str: | |
| """规范化趋势窗口参数,非法值回退到默认值。""" | |
| normalized = str(value or "").strip().lower() | |
| if normalized in {"24h", "7d", "30d"}: | |
| return normalized | |
| if normalized == "1d": | |
| return "24h" | |
| return DEFAULT_TREND_WINDOW | |
| def format_uptime(total_seconds: int) -> str: | |
| """格式化运行时长。""" | |
| total_seconds = max(0, int(total_seconds)) | |
| days, remainder = divmod(total_seconds, 86400) | |
| hours, remainder = divmod(remainder, 3600) | |
| minutes, seconds = divmod(remainder, 60) | |
| parts = [] | |
| if days: | |
| parts.append(f"{days}天") | |
| if days or hours: | |
| parts.append(f"{hours}小时") | |
| if days or hours or minutes: | |
| parts.append(f"{minutes}分钟") | |
| parts.append(f"{seconds}秒") | |
| return " ".join(parts) | |
| def get_process_uptime() -> str: | |
| """获取当前进程运行时长。""" | |
| if psutil is None: | |
| return "未知" | |
| created_at = psutil.Process(os.getpid()).create_time() | |
| return format_uptime(int(time.time() - created_at)) | |
| async def collect_admin_stats( | |
| provider: str, | |
| *, | |
| token_dao: Optional[TokenDAO] = None, | |
| request_log_dao: Optional[RequestLogDAO] = None, | |
| token_pool: Any = _TOKEN_POOL_SENTINEL, | |
| trend_window: str = DEFAULT_TREND_WINDOW, | |
| ) -> Dict[str, Any]: | |
| """聚合管理后台所需的 Token 与请求统计。""" | |
| token_dao = token_dao or get_token_dao() | |
| request_log_dao = request_log_dao or get_request_log_dao() | |
| if token_pool is _TOKEN_POOL_SENTINEL: | |
| token_pool = get_token_pool() | |
| trend_window = normalize_trend_window(trend_window) | |
| token_counts = await token_dao.get_provider_token_counts(provider) | |
| request_stats = await request_log_dao.get_provider_request_stats(provider) | |
| usage_trend = await request_log_dao.get_provider_usage_trend( | |
| provider, | |
| window=trend_window, | |
| ) | |
| pool_status: Dict[str, Any] = {} | |
| if isinstance(token_pool, TokenPool) or hasattr(token_pool, "get_pool_status"): | |
| pool_status = await token_pool.get_pool_status() if token_pool else {} | |
| total_tokens = _coerce_int(token_counts.get("total_tokens")) | |
| enabled_tokens = _coerce_int(token_counts.get("enabled_tokens")) | |
| user_tokens = _coerce_int(token_counts.get("user_tokens")) | |
| guest_tokens = _coerce_int(token_counts.get("guest_tokens")) | |
| unknown_tokens = _coerce_int(token_counts.get("unknown_tokens")) | |
| pool_total_tokens = _coerce_int(pool_status.get("total_tokens")) | |
| if pool_total_tokens == 0 and token_pool is None: | |
| pool_total_tokens = max(0, enabled_tokens - guest_tokens) | |
| available_tokens = _coerce_int(pool_status.get("available_tokens")) | |
| healthy_tokens = _coerce_int(pool_status.get("healthy_tokens")) | |
| unhealthy_tokens = _coerce_int(pool_status.get("unhealthy_tokens")) | |
| total_requests = _coerce_int(request_stats.get("total_requests")) | |
| successful_requests = _coerce_int(request_stats.get("successful_requests")) | |
| failed_requests = _coerce_int(request_stats.get("failed_requests")) | |
| input_tokens = _coerce_int(request_stats.get("input_tokens")) | |
| output_tokens = _coerce_int(request_stats.get("output_tokens")) | |
| total_consumed_tokens = _coerce_int(request_stats.get("total_tokens")) | |
| cache_creation_tokens = _coerce_int( | |
| request_stats.get("cache_creation_tokens") | |
| ) | |
| cache_read_tokens = _coerce_int(request_stats.get("cache_read_tokens")) | |
| cache_creation_requests = _coerce_int( | |
| request_stats.get("cache_creation_requests") | |
| ) | |
| cache_hit_requests = _coerce_int(request_stats.get("cache_hit_requests")) | |
| average_latency = round(float(request_stats.get("avg_duration") or 0.0), 2) | |
| average_first_token_latency = round( | |
| float(request_stats.get("avg_first_token_time") or 0.0), | |
| 2, | |
| ) | |
| total_cache_tokens = cache_creation_tokens + cache_read_tokens | |
| return { | |
| "total_tokens": total_tokens, | |
| "enabled_tokens": enabled_tokens, | |
| "user_tokens": user_tokens, | |
| "guest_tokens": guest_tokens, | |
| "unknown_tokens": unknown_tokens, | |
| "pool_total_tokens": pool_total_tokens, | |
| "available_tokens": available_tokens, | |
| "healthy_tokens": healthy_tokens, | |
| "unhealthy_tokens": unhealthy_tokens, | |
| "total_requests": total_requests, | |
| "successful_requests": successful_requests, | |
| "failed_requests": failed_requests, | |
| "input_tokens": input_tokens, | |
| "output_tokens": output_tokens, | |
| "total_consumed_tokens": total_consumed_tokens, | |
| "cache_creation_tokens": cache_creation_tokens, | |
| "cache_read_tokens": cache_read_tokens, | |
| "total_cache_tokens": total_cache_tokens, | |
| "cache_creation_requests": cache_creation_requests, | |
| "cache_hit_requests": cache_hit_requests, | |
| "average_latency": average_latency, | |
| "average_first_token_latency": average_first_token_latency, | |
| "trend_window": trend_window, | |
| "usage_trend": usage_trend, | |
| "total_consumed_tokens_display": format_compact_number( | |
| total_consumed_tokens | |
| ), | |
| "total_cache_tokens_display": format_compact_number( | |
| total_cache_tokens | |
| ), | |
| "input_tokens_display": format_compact_number(input_tokens), | |
| "output_tokens_display": format_compact_number(output_tokens), | |
| "success_rate": calculate_success_rate( | |
| successful_requests, | |
| total_requests, | |
| ), | |
| } | |