Worker and web processes are silent: no log file, nothing on stdout #11
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Reference
marvin8/xique#11
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
When a background job fails — for example the recommend job without a TMDB token — the only record of the failure anywhere is the message stored in the jobs table. The worker process prints nothing, writes no log file, and an operator has no way to see what the worker is doing or why a job failed without querying the database directly.
A missing TMDB token should show up as an error in the process output, not be silently swallowed. The web process has the same gap around its own lifecycle.
Expected behaviour, standard for server applications:
Found while manually testing the Trakt import flow: two recommend jobs failed and the worker gave no outward sign anything had happened.
Findings from the audit
grep -rn "import logging" src/returns nothing: the entire codebase has zero logging. NogetLogger, no handlers, no config.worker.main()→asyncio.run(run_worker(...))prints nothing, ever._dispatch_jobrecords failures viafail_jobonly; unexpected handler exceptions are swallowed into a generic token-free message and the traceback is dropped entirely.server.main()is a bareuvicorn.run(...)— uvicorn logs requests, but nothing xique-specific (startup config, schema verification) is logged.recommendjobs sit inerrorstatus (XIQUE_TMDB_TOKEN is not configured) with no outward sign on the machine.Plan of attack
Approach: stdlib
logging, two sinks on the root logger, configured once per process fromSettings.Settingsgainslog_level: str = "INFO"(validated against the stdlib level names, case-insensitive) andlog_file: Path | None = None→XIQUE_LOG_LEVEL,XIQUE_LOG_FILE.src/xique/logsetup.pywithconfigure_logging(settings): aStreamHandleron stdout at ERROR, and — whenlog_fileis set — a file handler at the configured level (DEBUG through CRITICAL). Format: timestamp, level, logger name, message.worker.py): lifecycle + job logging — startup with db path/poll interval, stale-job recovery count, job started/completed (DEBUG), known job failures (WARNING, reusing the existing token-freefail_jobmessage), unexpected handler exceptions at ERROR with traceback vialogger.exception. Idle cycles stay quiet at INFO.server.py): callconfigure_loggingbeforeuvicorn.run, log schema-version verification and startup. Uvicorn keeps its own handlers; ours attach to the root without touching theirs.XIQUE_LOG_LEVELandXIQUE_LOG_FILE(settings docs must stay in sync withconfig.py).Tests (TDD, RED first): level routing (DEBUG reaches the file but not stdout; ERROR reaches both),
log_file: Nonemeans stdout-only, invalidXIQUE_LOG_LEVELrejected by Settings, worker failure logs at WARNING with the token-free message, unexpected handler exception logs traceback at ERROR,main()entry points callconfigure_logging.Key files:
src/xique/config.py,src/xique/logsetup.py(new),src/xique/worker.py,src/xique/web/server.py,README.md,tests/.