fix(feeds): 3 warnings externes
3 fixes pour reduire le bruit de logs des sources publiques : wikimedia.py : ajoute User-Agent descriptif. WMF EventStreams refuse l'UA httpx par defaut avec 403 Forbidden. Le 1.0+URL descriptif est obligatoire pour le rate-limiting et les abuse reports. netzfrequenz.py : backoff exponentiel cap a 5 min sur les ws disconnect. La source (mainsfrequenz.de) est NXDOMAIN depuis mai 2026 ; on logguait toutes les 3 s soit ~28 800/jour. Avec backoff x1.6 et log uniquement attempt==1 ou attempt%10, on descend a ~30 log/jour. config.data-only.toml : opensky poll_seconds 20 -> 60. L'API anonyme est credit-based (10 req/min budget). 60s reste raisonnable pour le viz tout en restaurant le credit.
This commit is contained in:
@@ -65,9 +65,10 @@ ws_url = "wss://ws1.blitzortung.org:443/"
|
||||
[feeds.opensky]
|
||||
enabled = true
|
||||
url = "https://opensky-network.org/api/states/all"
|
||||
# API anonyme limitee a 1 req/15s. On laisse 20s de marge pour eviter
|
||||
# les 429 sous drift d'horloge.
|
||||
poll_seconds = 20
|
||||
# API anonyme : 10 req / 1 min credit-based. On reste a 60s pour ne
|
||||
# jamais epuiser le credit en cas de fork de process / restart rapide.
|
||||
# Les 429 vus en 2026-05 etaient dus au poll 15s/20s precedent.
|
||||
poll_seconds = 60
|
||||
bbox = [45.5, 4.6, 46.0, 5.2]
|
||||
|
||||
# -- Pouls numérique -------------------------------------------------------
|
||||
|
||||
@@ -22,10 +22,17 @@ async def run(ctx) -> None:
|
||||
url = cfg["ws_url"]
|
||||
time_dev = 0.0 # dérive intégrée (secondes)
|
||||
last_t = time.monotonic()
|
||||
# Backoff exponentiel cap a 5 minutes pour ne pas spammer un host
|
||||
# mort (mainsfrequenz.de NXDOMAIN depuis 2026-05). On log la
|
||||
# premiere et chaque dixieme reconnect uniquement.
|
||||
backoff = 3.0
|
||||
attempt = 0
|
||||
while True:
|
||||
try:
|
||||
async with websockets.connect(url, ping_interval=20) as ws:
|
||||
LOG.info("connected %s", url)
|
||||
backoff = 3.0 # reset on success
|
||||
attempt = 0
|
||||
async for msg in ws:
|
||||
text = msg if isinstance(msg, str) else msg.decode("utf-8", "ignore")
|
||||
m = _RE_F.search(text)
|
||||
@@ -45,5 +52,9 @@ async def run(ctx) -> None:
|
||||
ctx.send("dev", delta)
|
||||
ctx.send("time_dev", time_dev)
|
||||
except Exception as e: # noqa: BLE001
|
||||
LOG.warning("ws disconnected: %s — reconnecting", e)
|
||||
await asyncio.sleep(3.0)
|
||||
attempt += 1
|
||||
if attempt == 1 or attempt % 10 == 0:
|
||||
LOG.warning("ws disconnected (attempt %d, backoff %ds): %s",
|
||||
attempt, int(backoff), e)
|
||||
await asyncio.sleep(backoff)
|
||||
backoff = min(backoff * 1.6, 300.0)
|
||||
|
||||
@@ -27,12 +27,16 @@ async def run(ctx) -> None:
|
||||
cfg = ctx.cfg
|
||||
sample = float(cfg.get("sample_rate", 0.05)) # emit 5% des edits
|
||||
window = float(cfg.get("rate_window_s", 5.0))
|
||||
# WMF EventStreams refuse l'User-Agent par defaut httpx (403). Il
|
||||
# faut une string descriptive + URL/email pour les abuse reports.
|
||||
headers = {
|
||||
"Accept": "text/event-stream",
|
||||
"User-Agent": "av-live-data-feeds/1.0 (https://github.com/electron-rare/AV-Live)",
|
||||
}
|
||||
while True:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=None) as cli:
|
||||
async with cli.stream("GET", URL,
|
||||
headers={"Accept": "text/event-stream"}
|
||||
) as r:
|
||||
async with cli.stream("GET", URL, headers=headers) as r:
|
||||
r.raise_for_status()
|
||||
bucket = 0
|
||||
bucket_start = time.monotonic()
|
||||
|
||||
Reference in New Issue
Block a user