Context
Follow-up from the live structured server-log console (#178 / PR #180).
In the new Server Logs panel, every request to a Flask service (duckdb-service, image-service) currently produces two ring entries:
- The canonical structured access entry —
GET /health 200 0.1ms at the correct level (info/warn/error by status). This is the intended Phase-2 access log.
- Werkzeug's own request line (e.g.
127.0.0.1 - - [date] "GET /health HTTP/1.1" 200 -), which the stdout/stderr tee captures from stderr and therefore tags as error level (red), even for a successful 200.
The duplication plus the misleading red coloring is acknowledged as accepted in code (duckdb-service/app.py _access_log_finish: "werkzeug's own request line is still tee-captured; this is the canonical entry"), but it makes the panel noisier than intended and paints healthy 200s red.
Because docker-compose.prod.yml still runs the Flask dev server (gunicorn is noted there as a future hardening pass), this noise reaches prod, not just dev.
Proposal
Silence Werkzeug's built-in access logger in both Flask services so only the structured after_request entry lands in the ring, e.g. at import time before serving:
import logging
logging.getLogger("werkzeug").setLevel(logging.ERROR) # or .disabled = True for access lines
Keep the two log_ring.py files byte-identical (a test enforces this) and apply the change symmetrically to both services.
Acceptance
- A successful request to a Flask service yields exactly one ring entry (
GET /path 200 N.Nms), at the right level — no duplicate werkzeug line, no false red.
- The structured access log and error-branch logging are unaffected.
- Verified in the Server Logs panel for both
duckdb-service and image-service.
Discovered while manually testing PR #180.
Context
Follow-up from the live structured server-log console (#178 / PR #180).
In the new Server Logs panel, every request to a Flask service (
duckdb-service,image-service) currently produces two ring entries:GET /health 200 0.1msat the correct level (info/warn/errorby status). This is the intended Phase-2 access log.127.0.0.1 - - [date] "GET /health HTTP/1.1" 200 -), which the stdout/stderr tee captures from stderr and therefore tags aserrorlevel (red), even for a successful200.The duplication plus the misleading red coloring is acknowledged as accepted in code (
duckdb-service/app.py_access_log_finish: "werkzeug's own request line is still tee-captured; this is the canonical entry"), but it makes the panel noisier than intended and paints healthy 200s red.Because
docker-compose.prod.ymlstill runs the Flask dev server (gunicorn is noted there as a future hardening pass), this noise reaches prod, not just dev.Proposal
Silence Werkzeug's built-in access logger in both Flask services so only the structured
after_requestentry lands in the ring, e.g. at import time before serving:Keep the two
log_ring.pyfiles byte-identical (a test enforces this) and apply the change symmetrically to both services.Acceptance
GET /path 200 N.Nms), at the right level — no duplicate werkzeug line, no false red.duckdb-serviceandimage-service.Discovered while manually testing PR #180.