Skip to content

Configurable logging system + exception/content logging fixes - #23

Merged
damienlaine merged 2 commits into
nextfrom
feat/logging
Jun 19, 2026
Merged

damienlaine merged 2 commits into
nextfrom
feat/logging

Conversation

@damienlaine

Copy link
Copy Markdown
Member

Why

Logging was 5 scattered basicConfig() calls, plain text on stdout only, with a single DEBUG toggle. No way to ship logs to a centralized system. This makes logging configurable like the LinTO Studio API (Winston): selectable sinks, text or JSON, per-sink levels.

Commit 1 — feature: configurable logging

  • Central app/core/logging_config.py (setup_logging), called once per process (API, Celery, seeds), replacing the scattered basicConfig calls.
  • Driven by env vars (LOG_LEVEL, LOG_FORMAT text|json, LOG_NAME, per-sink levels) or a full dictConfig JSON file via LOGGING_CONFIG_FILE (Winston WINSTON_CONFIG_PATH equivalent).
  • Sinks: console, rotating file, non-blocking HTTP POST (background queue), Google Cloud Logging / Stackdriver (optional dep).
  • JSON logs: ISO-8601 timestamps with millisecond precision, service label per process, extra={...} fields preserved.
  • uvicorn access logs flow through the same sinks (log_config=None), /healthcheck still filtered.
  • Adds python-json-logger, docs/LOGGING_GUIDE.md, and tests/test_logging_config.py (19 tests).

Commit 2 — fix: exception & content logging quality

  • Tracebacks: 71 except handlers logged only the exception string. Converted logger.error -> logger.exception and added exc_info=True to warning/critical inside except blocks. logger.exception count 1 -> 83, exc_info=True 0 -> 16.
  • Privacy: stopped dumping LLM responses, extracted document content and prompt bodies in logs (kept lengths, field names and ids). Notably the JIT-extraction INFO log no longer logs document content.

Verification

  • AST check: every logger.exception / exc_info=True sits inside an active except (no "NoneType: None").
  • Only logging lines changed in the reviewed files — no control-flow/behavior changes.
  • py_compile OK on all changed files; 775 tests collect with no import errors; 186 passed / 0 failed on the subset touching the changed modules.

Notes

  • google-cloud-logging is left commented in requirements.txt (optional, lazy-imported); uncomment to enable the Stackdriver sink.
  • Default behavior is unchanged: text logs on stdout. Set LOG_FORMAT=json for aggregators.

Centralize logging in app/core/logging_config.py (setup_logging), replacing
the scattered basicConfig calls. Driven by env vars (LOG_LEVEL, LOG_FORMAT
text|json, LOG_NAME, per-sink levels) or a full dictConfig file
(LOGGING_CONFIG_FILE). Sinks: console, rotating file, non-blocking HTTP POST,
and Google Cloud Logging (Stackdriver). JSON logs use ISO-8601 timestamps with
millisecond precision. Wires the API server, Celery workers and seed scripts.

Adds python-json-logger, docs/LOGGING_GUIDE.md and tests.
…ntent

In except blocks, convert logger.error to logger.exception and add
exc_info=True to logger.warning/critical so stack traces are captured
(previously 71 handlers logged only the exception string). Stop dumping
LLM responses, extracted document content and prompt bodies in logs;
keep lengths, field names and ids instead (notably the JIT extraction
INFO log and the metadata-extraction previews).
@damienlaine
damienlaine merged commit ae37936 into next Jun 19, 2026
5 checks passed
@damienlaine
damienlaine deleted the feat/logging branch June 19, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant