fix(logs): keep polling reads and a channel-less account out of the warnings

The reads the frontend polls (unread counts, /api/me, the download index,
sync status, subtitle progress) are logged at DEBUG: at INFO they were ~95%
of the stored log on prod. A scheduler job failure and a playlist sync
failure carry event codes, and a Google account without a YouTube channel
has an empty playlist list instead of a warning every six hours.
This commit is contained in:
2026-09-19 04:51:31 +02:00
parent 29094f5f51
commit 3ee00fb051
6 changed files with 136 additions and 10 deletions
+32
View File
@@ -219,6 +219,14 @@ def _client() -> TestClient:
raise HTTPException(status_code=400, detail={"code": "bad_cursor"})
return {"ok": True}
@app.get("/api/messages/unread_count")
def _unread():
return {"count": 0}
@app.post("/api/messages/unread_count")
def _unread_write():
return {"ok": True}
@app.get("/boom")
def _boom():
raise RuntimeError("kaboom")
@@ -323,6 +331,30 @@ def test_the_log_consoles_own_reads_are_debug_but_its_failures_are_not(sink):
assert sink.objects()[-1]["level"] == "WARNING"
def test_a_polled_read_is_debug_a_write_to_the_same_route_is_not(sink):
# One open tab polled the unread counts, /api/me and the download index every 30 s: at INFO
# that was ~95% of the stored log on prod.
http = logging.getLogger("siftlode.http")
http.setLevel(logs.TRACE)
client = _client()
client.get("/api/messages/unread_count")
assert sink.objects()[-1]["level"] == "DEBUG"
client.post("/api/messages/unread_count")
assert sink.objects()[-1]["level"] == "INFO"
client.get("/api/videos/abc")
assert sink.objects()[-1]["level"] == "INFO"
def test_every_polled_route_is_a_route_the_app_has():
# The list names route TEMPLATES; one renamed on the router side would silently fall back to
# INFO, so the list is held to the app's own routes.
from app.main import app
# The schema, not `app.routes`: FastAPI 0.141 keeps an included router behind a wrapper there.
gets = {path for path, ops in app.openapi()["paths"].items() if "get" in ops}
assert logs._POLLED_ROUTES - gets == set()
def test_a_failing_request_is_logged_by_status_and_an_unhandled_error_is_logged_at_all(sink):
client = _client()
client.get("/api/videos/missing/deeper") # 404 from the router