import datetime from typing import Optional from django.core.management.base import BaseCommand from django.utils import timezone from domains.models import Domain, DomainTrafficDaily from core.goedge_client import GoEdgeClient class Command(BaseCommand): help = '从 GoEdge 拉取每日流量统计并写入 DomainTrafficDaily(默认处理昨天的数据)' def add_arguments(self, parser): parser.add_argument('--days', type=int, default=1, help='拉取最近N天(默认1)') parser.add_argument('--server-id', type=int, default=0, help='仅处理指定的 serverId') def handle(self, *args, **options): days: int = options['days'] server_id_filter: int = options['server_id'] client = GoEdgeClient() qs = Domain.objects.exclude(edge_server_id__isnull=True).exclude(edge_server_id__exact='') if server_id_filter: qs = qs.filter(edge_server_id=server_id_filter) processed = 0 for domain in qs: server_id = int(domain.edge_server_id) try: daily_stats = client.find_latest_server_daily_stats(server_id=server_id, days=days) bw_stats = client.find_daily_bandwidth_stats(server_id=server_id, days=days, algo='avg') except Exception as e: self.stderr.write(self.style.ERROR(f'域名 {domain.name} 拉取失败: {e}')) continue # 将带宽按day映射 bw_by_day = {} for s in bw_stats or []: day = s.get('day') bytes_per_sec = s.get('bytes') or 0 # 转换为 Mbps:bytes/sec * 8 / 1_000_000 mbps = (bytes_per_sec * 8) / 1_000_000 if bytes_per_sec else 0.0 bw_by_day[day] = mbps for s in daily_stats or []: day_str: Optional[str] = s.get('day') # YYYYMMDD if not day_str: continue try: day_date = datetime.datetime.strptime(day_str, '%Y%m%d').date() except Exception: continue bytes_used = int(s.get('bytes') or 0) peak_mbps = float(bw_by_day.get(day_str) or 0.0) obj, created = DomainTrafficDaily.objects.update_or_create( domain=domain, day=day_date, defaults={ 'bytes': bytes_used, 'peak_bandwidth_mbps': peak_mbps, } ) processed += 1 self.stdout.write(self.style.SUCCESS(f'完成,写入/更新 {processed} 条日流量记录。'))