Repository navigation
fix: avoid fabricated correlation IDs outside active HTTP request contexts #125
Description
Summary
When the library is initialized for Flask (and potentially Quart or Connexion), application logs emitted outside an active HTTP request context can contain a freshly generated, apparently valid correlation_id instead of the expected empty value ("-"). Subsequent log records can receive different fabricated IDs, making unrelated startup, shutdown, and Gunicorn access logs appear associated with real requests.
This behavior was identified during a cross-framework maintenance audit. It needs a regression test on current master before implementation.
Related history
- Related historical issue: Using root logger + flask outside of flask request context throws RuntimeError #61 ("Using root logger + flask outside of flask request context throws RuntimeError"). That issue addressed an exception when the request proxy was unbound; this issue is about the silent generation of misleading correlation IDs, not an exception.
- Related support question: gunicorn flask and json-logging-python combine together #25 (Gunicorn + Flask).
- Distinct from RuntimeError: dictionary changed size during iteration #89/Fix request lookup when frame locals mutate #120 (frame-locals mutation) and Cant access correlation id , help #80/fix(fastapi): propagate request correlation across async tasks and sync worker threads #123 (FastAPI cross-thread correlation propagation).
Suspected cause
FlaskRequestInfoExtractor.get_current_request()and analogous framework extractors return a framework request proxy even when it is unbound.RequestUtil.get_correlation_id()injson_logging/util.pycurrently distinguishes onlyrequest is Nonefrom an active request.- With a proxy but no request context, the code can generate a UUID. The framework-specific
set_correlation_id()catches the failure to store it, leaving a new UUID to be generated for the next log.
Relevant paths: json_logging/util.py, json_logging/framework/flask/__init__.py, json_logging/framework/quart/__init__.py, and json_logging/framework/connexion/__init__.py.
Expected behavior
- An application log emitted without an active HTTP request must report
correlation_id: "-"(or preserve an explicitly supplied per-log correlation value), not generate and discard a random ID. - Application logs inside a request must continue to share the supplied correlation header or one stable generated value.
- No changes to the default JSON schema, unrelated frameworks, or global logger behavior.
Reproduction and tests requested
- Enable JSON logging for Flask, configure a capture handler, and log twice before entering an HTTP request context and/or after the request completes.
- Check whether both records contain non-empty, unrelated generated IDs rather than
"-". - Repeat for Quart and Connexion where supported and include a Gunicorn worker example where practical.
- Confirm the regression test fails on unmodified
masterand passes with the fix. - Confirm normal request logging, supplied-header IDs, generated IDs, and sequential/concurrent request isolation still work.
Proposed minimal fix
Use framework-native active-request-context detection to return None when there is no real request; keep RequestUtil's existing no-request EMPTY_VALUE behavior. Avoid global mutable context and broad refactors.
Acceptance criteria
- Deterministic regression covering the original failure
- No random correlation ID outside active HTTP requests
- Stable, correct correlation IDs inside requests
- Backward-compatible log fields and values inside requests
- Relevant unit tests, smoke tests, and blocking lint checks pass
- Changelog entry if behavior is modified
Release candidate: 1.6.0 if independently reviewed, tested, and ready by the release freeze; otherwise follow-up patch release.
Activity
test: restore framework logger state and avoid temp-dir leaks
fix(connexion): keep supplied correlation IDs outside the Flask reque…
docs: add tested Gunicorn and Flask integration example
docs: add tested Gunicorn and Flask integration example (#131)
chore(release): prepare json-logging 1.6.0
chore(release): prepare json-logging 1.6.0 (#132)
fix: prevent fabricated correlation IDs outside active requests (bobb…