c094eb88fa
Adds src/ (scripts, raw measurement logs, derived data, report source), tests/, LICENSE (MIT, code) and LICENSE-DATA.md (CC BY 4.0 for the survey's data; third-party terms). The report is updated to the current site; the v1 and v2 data hand-off files are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
46 lines
2.5 KiB
Python
46 lines
2.5 KiB
Python
"""Turn our own servers' ping logs into live-grid cells.
|
|
|
|
Each server is pinned to the RIPE anchor in its own city, with its ping to that
|
|
anchor as the allowance (the same rule as the Globalping probes). Server-to-
|
|
server and server-to-anchor measurements then become cells between anchor
|
|
cities, so they share the cable routes already computed for those cities.
|
|
Honolulu has no anchor; it is its own site at the data-centre city (within
|
|
about 1 km of the coordinates used). Every pair gets the page's 25 km slack.
|
|
|
|
python3 vps_analyze.py -> data/vps_cells.json
|
|
"""
|
|
import glob, json, os, re, statistics
|
|
from collections import defaultdict
|
|
from measure import TARGETS
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
STATE = json.load(open(os.path.join(HERE, "data/vps/state.json")))
|
|
ANCHOR = {t[2]: t[0] for t in TARGETS} # anchor fqdn -> city
|
|
LOCAL = {"syd": "Sydney", "mel": "Melbourne", "jnb": "Johannesburg", "scl": "Santiago", "sao": "São Paulo",
|
|
"lax": "Los Angeles", "icn": "Seoul"} # server -> city of the anchor it is pinned to
|
|
RX = re.compile(r"^(\S+) (\S+) (\S+) .*?(\d+) packets transmitted, (\d+) received.*?= ([\d.]+)/([\d.]+)/([\d.]+)/([\d.]+) ms")
|
|
|
|
runs = defaultdict(list) # (src code, target name) -> per-run minimum RTTs
|
|
for n in STATE["nodes"]:
|
|
f = os.path.join(HERE, "data/vps", n["code"], "ping.log")
|
|
if not os.path.exists(f):
|
|
continue
|
|
for line in open(f):
|
|
m = RX.match(line)
|
|
if m:
|
|
runs[(n["code"], m.group(2))].append(float(m.group(6)))
|
|
|
|
site = lambda code_or_target: LOCAL.get(code_or_target) or ANCHOR.get(code_or_target) or ("Honolulu" if code_or_target == "hnl" else None)
|
|
local = {c: min(runs[(c, a)]) for c, city in LOCAL.items() for a, ac in ANCHOR.items() if ac == city and runs.get((c, a))}
|
|
|
|
cells = []
|
|
for (src, tgt), mins in runs.items():
|
|
a, b = site(src), site(tgt)
|
|
if not a or not b or a == b:
|
|
continue
|
|
allow = local.get(src, 0.0) + (local.get(tgt, 0.0) if tgt in LOCAL else 0.0)
|
|
cells.append(dict(src=src, tgt=tgt, a=a, b=b, rtt=round(min(mins), 2), median=round(statistics.median(mins), 2),
|
|
runs=len(mins), allow=round(allow, 2), slack_km=25))
|
|
json.dump(dict(cells=cells, local=local, nodes=STATE["nodes"]), open(os.path.join(HERE, "data/vps_cells.json"), "w"), indent=1)
|
|
print(f"{len(cells)} cells from {len(runs)} server-target series; local allowances: { {k: round(v, 2) for k, v in local.items()} }")
|