Initial commit

This commit is contained in:
2025-11-18 03:36:49 +08:00
commit d17c7efb3c
7078 changed files with 831480 additions and 0 deletions

View File

@@ -0,0 +1 @@
"""Django management package for domains app."""

View File

@@ -0,0 +1,67 @@
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
# 转换为 Mbpsbytes/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} 条日流量记录。'))

View File

@@ -0,0 +1,74 @@
import datetime
from typing import Dict
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils import timezone
from domains.models import Domain, DomainTrafficDaily
from core.goedge_client import GoEdgeClient
class Command(BaseCommand):
help = '从 GoEdge 读取各域名serverId的最近每日流量并写入 DomainTrafficDaily'
def add_arguments(self, parser):
parser.add_argument('--days', type=int, default=35, help='拉取最近N天数据默认35')
parser.add_argument('--only-active', action='store_true', dest='only_active', default=False, help='仅拉取状态为active的域名')
# 兼容文档中的别名参数
parser.add_argument('--active-only', action='store_true', dest='only_active', help='参数别名,等同 --only-active')
@transaction.atomic
def handle(self, *args, **options):
days: int = options['days']
only_active: bool = options['only_active']
qs = Domain.objects.exclude(edge_server_id__isnull=True)
if only_active:
qs = qs.filter(status=Domain.STATUS_ACTIVE)
domains = list(qs)
if not domains:
self.stdout.write(self.style.WARNING('没有可拉取的域名(缺少 edge_server_id'))
return
client = GoEdgeClient()
total_written = 0
for d in domains:
server_id = int(d.edge_server_id)
try:
stats = client.find_latest_server_daily_stats(server_id=server_id, days=days)
except Exception as e:
self.stderr.write(self.style.ERROR(f'[domain={d.name}] 拉取失败:{e}'))
continue
# 解析并入库
for s in stats:
day_str = s.get('day')
bytes_val = int(s.get('bytes') or 0)
peak_mbps = float(s.get('peakBandwidthMbps') or 0.0)
# 将 day 格式 YYYYMMDD 转为 date
try:
day_date = datetime.datetime.strptime(day_str, '%Y%m%d').date()
except Exception:
# 某些版本可能返回 YYYY-MM-DD
try:
day_date = datetime.datetime.strptime(day_str, '%Y-%m-%d').date()
except Exception:
self.stderr.write(self.style.WARNING(f'无法解析日期:{day_str}'))
continue
obj, created = DomainTrafficDaily.objects.update_or_create(
domain=d,
day=day_date,
defaults={
'bytes': bytes_val,
'peak_bandwidth_mbps': peak_mbps,
}
)
total_written += 1
self.stdout.write(self.style.SUCCESS(f'[domain={d.name}] 写入 {len(stats)}'))
self.stdout.write(self.style.SUCCESS(f'完成,总写入记录:{total_written}'))