67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
|
|
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} 条日流量记录。'))
|