feat(config): Add TracerProvider support for declarative config#4985
feat(config): Add TracerProvider support for declarative config#4985MikeGoldsmith wants to merge 11 commits intoopen-telemetry:mainfrom
Conversation
Implements create_resource() and create_propagator()/configure_propagator() for the declarative file configuration. Resource creation does not read OTEL_RESOURCE_ATTRIBUTES or run any detectors (matches Java/JS SDK behavior). Propagator configuration always calls set_global_textmap to override Python's default tracecontext+baggage, setting a noop CompositePropagator when no propagator is configured. Assisted-by: Claude Sonnet 4.6
Assisted-by: Claude Sonnet 4.6
- _resource.py: refactor _coerce_attribute_value to dispatch table to avoid too-many-return-statements; fix short variable names k/v -> attr_key/attr_val; fix return type of _sdk_default_attributes to dict[str, str] to satisfy pyright - _propagator.py: rename short variable names e -> exc, p -> propagator - test_resource.py: move imports to top level; split TestCreateResource (25 methods) into three focused classes to satisfy too-many-public-methods - test_propagator.py: add pylint disable for protected-access Assisted-by: Claude Sonnet 4.6
- replace _sdk_default_attributes() with _DEFAULT_RESOURCE from resources module - move _coerce_bool into dispatch tables for both scalar and array bool types, fixing a bug where bool_array with string values like "false" would coerce incorrectly via plain bool() (non-empty string -> True) - add test for bool_array with string values to cover the bug Assisted-by: Claude Sonnet 4.6
… into mike/config-resource-propagator
Implements create_tracer_provider() and configure_tracer_provider() for the declarative configuration pipeline (tracking issue open-telemetry#3631 step 5). Key behaviors: - Never reads OTEL_TRACES_SAMPLER or OTEL_SPAN_*_LIMIT env vars; absent config fields use OTel spec defaults (matching Java SDK behavior) - Default sampler is ParentBased(root=ALWAYS_ON) per the OTel spec - SpanLimits absent fields use hardcoded defaults (128) not env vars - configure_tracer_provider(None) is a no-op per spec/Java/JS behavior - OTLP exporter fields pass None through so the exporter reads its own env vars for unspecified values - Lazy imports for optional OTLP packages with ConfigurationError on missing - Supports all 4 ParentBased delegate samplers Assisted-by: Claude Sonnet 4.6
Assisted-by: Claude Sonnet 4.6
- add # noqa: PLC0415 to lazy OTLP imports (ruff also enforces this) - move SDK imports to top-level (BatchSpanProcessor, etc.) - convert test helper methods to @staticmethod to satisfy no-self-use - add pylint: disable=protected-access for private member access in tests - fix return type annotation on _create_span_processor Assisted-by: Claude Sonnet 4.6
Assisted-by: Claude Sonnet 4.6
| return CompositePropagator(propagators) | ||
|
|
||
|
|
||
| def configure_propagator(config: Optional[PropagatorConfig]) -> None: |
There was a problem hiding this comment.
Correct me if I'm wrong, but did we want to silently disable trace context, baggage propagation for an empty propagator section in the config file?
There was a problem hiding this comment.
The intention here is "what you see is what you get" (WYSIWYG) semantics as defined in the declarative config contributing guide:
implementations should minimize the amount of magic that occurs as a result of the absence of an optional property
So if propagators is absent or empty in the config file, the intent is that no propagators are configured — not that we fall back to the SDK defaults of tracecontext+baggage. WYSIWYG: there are no propagators in the config, you get no propagators.
This is intentional and consistent with how e.g. an absent meter_provider results in a noop meter provider rather than a default one with a periodic reader and OTLP exporter.
Assisted-by: Claude Sonnet 4.6
Description
Implements
create_tracer_provider()andconfigure_tracer_provider()for the declarative configuration pipeline, as part of the ongoing work tracked in the following PR:Note
This PR is based on #4979 (Resource & Propagator creation) which must be merged first. The extra commits at the base of this branch will be dropped once that PR lands.
What's included
_tracer_provider.py: creates an SDKTracerProviderfrom declarative configalways_on,always_off,trace_id_ratio_based,parent_based(with all 4 delegate samplers)BatchSpanProcessorandSimpleSpanProcessorConfigurationErrorif not installedSpanLimitsand sampler use OTel spec defaults for absent fields — no env-var leakageconfigure_tracer_provider(None)is a no-op per spec/Java/JS behaviorEnv-var suppression
Python's
TracerProviderreadsOTEL_TRACES_SAMPLERwhensampler=None, andSpanLimitsreadsOTEL_SPAN_*_LIMITwhen fields areNone. To match the spec's "what you see is what you get" semantics (and Java SDK behavior), we always pass explicit values — defaulting to spec defaults (e.g.ParentBased(root=ALWAYS_ON), 128 for count limits) rather than falling through to env vars.Type of change
How Has This Been Tested?
tests/_configuration/test_tracer_provider.pyOTEL_TRACES_SAMPLER,OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT) are not read when config is usedDoes This PR Require a Contrib Repo Change?
Checklist:
Assisted-by: Claude Sonnet 4.6