The add_otel_trace_context structlog processor currently only lives in the structlog.configure() pipeline, not in the foreign_pre_chain used by ProcessorFormatter for standard library logging events.
This means any module using logging.getLogger(__name__) (e.g. task_processor.processor) does not get trace_id / span_id injected into its log output — even when an active OTel span exists.
How to reproduce
- Run the API + task processor with
OTEL_EXPORTER_OTLP_ENDPOINT set and LOG_FORMAT=json.
- Trigger a request that enqueues a task.
- Observe that task processor log events (e.g. "Failed to execute task") lack
trace_id and span_id fields.
Expected
All log events emitted while an OTel span is active — regardless of whether they originate from structlog or stdlib logging — should include trace_id and span_id.
Fix
Add add_otel_trace_context to the foreign_pre_chain in setup_logging() (common/core/logging.py), so that ProcessorFormatter also injects trace context into stdlib log records.
Found while testing #197.
The
add_otel_trace_contextstructlog processor currently only lives in thestructlog.configure()pipeline, not in theforeign_pre_chainused byProcessorFormatterfor standard libraryloggingevents.This means any module using
logging.getLogger(__name__)(e.g.task_processor.processor) does not gettrace_id/span_idinjected into its log output — even when an active OTel span exists.How to reproduce
OTEL_EXPORTER_OTLP_ENDPOINTset andLOG_FORMAT=json.trace_idandspan_idfields.Expected
All log events emitted while an OTel span is active — regardless of whether they originate from structlog or stdlib
logging— should includetrace_idandspan_id.Fix
Add
add_otel_trace_contextto theforeign_pre_chaininsetup_logging()(common/core/logging.py), so thatProcessorFormatteralso injects trace context into stdlib log records.Found while testing #197.