I run a small household alerting script that polls the USGS summary feeds every five minutes. For about eight months it worked fine. Then in late spring I noticed a cluster of M2.x events under a swarm area that never triggered an alert, even though the M3.0+ events in the same sequence came through normally. Version at the time: Python 3.11, requests 2.31, no database, just a flat JSONL file of everything I had seen. Feed volume around 400-900 events per day depending on global activity.
The feed I was using was the 2.5-day, all-magnitudes GeoJSON summary. My parser did the obvious thing:
for feat in data["features"]:
mag = feat["properties"]["mag"]
if mag >= 2.0:
handle(feat)
That looks safe. The bug was that USGS reports some events with "mag": null in the properties, particularly early revisions or events where magnitude was computed from a different phase set. In Python, None >= 2.0 raises a TypeError inside the loop, and because I had a bare except around the whole poll, the entire batch was dropped and I only saw a single line in the log. So a single null-magnitude event could silently kill a whole five-minute window, which is exactly how a swarm’s smaller events disappear while the bigger ones, arriving in a later poll, still get through.
What I changed: guard on type, and never let one feature abort the batch.
for feat in data["features"]:
props = feat.get("properties") or {}
mag = props.get("mag")
if not isinstance(mag, (int, float)):
continue
if mag >= 2.0:
handle(feat)
I also moved the try/except inside the loop, so a malformed feature is skipped and logged with its id, not swallowed. The cost is that I now write more log lines than before, and I had to add a dedupe key because re-polling the same summary feed returns the same events repeatedly; I key on feat["id"] and keep a set of the last few thousand. That set is bounded, so a very long quiet period can let old IDs fall out and a re-poll can double-handle an event, which is harmless for alerts but will inflate any counts I do later.
Where this breaks: the summary feeds are revised, so magnitude can change after first publication, and my dedupe by ID means I ignore the revision. For a swarm rate calculation that matters, because an M2.4 upgraded to M2.7 later is still counted once at its first value. Also, null is not the only oddity; I have seen mag delivered as a string in cached third-party mirrors of the feed, so if you are not hitting USGS directly, the isinstance check will skip everything and you will get silence, not an error. That one cost me an afternoon.
If you poll a summary feed and keep state, how do you handle post-publication magnitude revisions without double-counting?
0 条评论
还没有评论,写下第一条。