Skip to content

feat(config): add resource and propagator creation from declarative config#4979

Merged
xrmx merged 14 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-resource-propagator
Mar 25, 2026
Merged

feat(config): add resource and propagator creation from declarative config#4979
xrmx merged 14 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-resource-propagator

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

@MikeGoldsmith MikeGoldsmith commented Mar 13, 2026

Description

Implements step 3 of the declarative configuration work (see below), resource and propagator creation from a parsed config file.

Adds:

  • create_resource(config) — builds an SDK Resource from the declarative config model without reading OTEL_RESOURCE_ATTRIBUTES. Starts from SDK telemetry defaults (telemetry.sdk.*), merges attributes (with AttributeType coercion) and attributes_list (URL-decoded, lower priority), and adds service.name=unknown_service as the lowest-priority default (detectors and explicit config attributes can override it).
  • create_propagator(config) — builds a CompositePropagator from the config's composite list and/or composite_list string. Deduplicates by propagator type. Returns an empty CompositePropagator (noop) when no propagator is configured.
  • configure_propagator(config) — calls set_global_textmap to override Python's default env-var-based propagator setup.
  • ConfigurationError moved to _exceptions.py to break a circular import introduced when file/__init__.py re-exports the new functions.
  • _run_detectors() stub and _filter_attributes() — shared foundations for resource detector support. Detectors are opt-in: nothing runs unless explicitly listed under detection_development.detectors in the config. The include/exclude attribute filter mirrors other SDK behaviour. Individual detector PRs build on top of this.

All functions are exported from opentelemetry.sdk._configuration.file.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

43 new unit tests covering:

  • All AttributeType coercions (string, bool, int, double, and array variants)
  • attributes_list parsing: priority vs explicit attributes, URL decoding, = in values, invalid pairs
  • schema_url passthrough
  • OTEL_RESOURCE_ATTRIBUTES env var is NOT read
  • All four built-in propagators (tracecontext, baggage, b3, b3multi)
  • composite + composite_list merging and deduplication
  • none and empty entries in composite_list skipped
  • Missing entry point raises ConfigurationError
  • configure_propagator calls set_global_textmap

Does This PR Require a Contrib Repo Change?

  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

Assisted-by: Claude Sonnet 4.6

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
@MikeGoldsmith MikeGoldsmith requested a review from a team as a code owner March 13, 2026 13:11
@MikeGoldsmith MikeGoldsmith moved this to Ready for review in Python PR digest Mar 13, 2026
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
Copy link
Copy Markdown
Member

@pmcollins pmcollins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Minor comments below.

Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py Outdated
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py Outdated
- 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
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py Outdated
…erge

- collapse _SCALAR_COERCIONS and _ARRAY_COERCIONS into a single _COERCIONS
  dict using an _array() factory, reducing _coerce_attribute_value to two lines
- process attributes_list before attributes so explicit attributes naturally
  overwrite list entries without needing an explicit guard

Assisted-by: Claude Sonnet 4.6
Copy link
Copy Markdown
Member

@pmcollins pmcollins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM once suggestions are addressed (I added a typing suggestion).

Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_resource.py Outdated
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Mar 17, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

@MikeGoldsmith MikeGoldsmith force-pushed the mike/config-resource-propagator branch 2 times, most recently from 85575ff to 430ae83 Compare March 17, 2026 16:35
@MikeGoldsmith
Copy link
Copy Markdown
Member Author

I think the Misc/tracecontext failure is a flakey test. Please can someone, re-run it for me?

Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_logger_provider.py Outdated
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_logger_provider.py Outdated
Assisted-by: Claude Sonnet 4.6
Adds _run_detectors() stub and _filter_attributes() to create_resource(),
providing the shared scaffolding for detector PRs to build on. Detectors
are opt-in: nothing runs unless explicitly listed under
detection_development.detectors in the config. The include/exclude
attribute filter mirrors other SDK behaviour.

Assisted-by: Claude Sonnet 4.6
Merges service.name=unknown_service into base before running detectors,
so detectors (e.g. service) can override it. Previously it was added to
config_attrs and merged last, which would have silently overridden any
detector-provided service.name.

Assisted-by: Claude Sonnet 4.6
@MikeGoldsmith MikeGoldsmith force-pushed the mike/config-resource-propagator branch from 367aa82 to 103ff08 Compare March 20, 2026 14:20
Comment thread opentelemetry-sdk/tests/_configuration/test_propagator.py
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/file/_loader.py Outdated
Import directly from _exceptions.py since this is new code with no existing
dependents on the _loader module path.

Assisted-by: Claude Sonnet 4.6
@xrmx xrmx merged commit 6929c69 into open-telemetry:main Mar 25, 2026
508 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for review to Done in Python PR digest Mar 25, 2026
@MikeGoldsmith MikeGoldsmith added the config Issues and PRs related to implementing Declarative Config label Apr 8, 2026
@MikeGoldsmith MikeGoldsmith deleted the mike/config-resource-propagator branch April 9, 2026 14:12
Vitexus pushed a commit to Vitexus/opentelemetry-python that referenced this pull request Apr 30, 2026
…onfig (open-telemetry#4979)

* config: add resource and propagator creation from declarative config

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

* update changelog with PR number

Assisted-by: Claude Sonnet 4.6

* fix pylint, pyright and ruff errors in resource/propagator config

- _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

* address review feedback: use _DEFAULT_RESOURCE, fix bool_array coercion

- 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

* fix linter

* address review feedback: single coercion table, simplify attributes merge

- collapse _SCALAR_COERCIONS and _ARRAY_COERCIONS into a single _COERCIONS
  dict using an _array() factory, reducing _coerce_attribute_value to two lines
- process attributes_list before attributes so explicit attributes naturally
  overwrite list entries without needing an explicit guard

Assisted-by: Claude Sonnet 4.6

* use Callable type annotation on _array helper

Assisted-by: Claude Sonnet 4.6

* add detection infrastructure foundations for resource detectors

Adds _run_detectors() stub and _filter_attributes() to create_resource(),
providing the shared scaffolding for detector PRs to build on. Detectors
are opt-in: nothing runs unless explicitly listed under
detection_development.detectors in the config. The include/exclude
attribute filter mirrors other SDK behaviour.

Assisted-by: Claude Sonnet 4.6

* move service.name default into base resource

Merges service.name=unknown_service into base before running detectors,
so detectors (e.g. service) can override it. Previously it was added to
config_attrs and merged last, which would have silently overridden any
detector-provided service.name.

Assisted-by: Claude Sonnet 4.6

* remove unused logging import from _propagator.py

Assisted-by: Claude Sonnet 4.6

* add test verifying OTEL_PROPAGATORS env var is ignored by configure_propagator

Assisted-by: Claude Sonnet 4.6

* remove backwards compat re-export of ConfigurationError from _loader.py

Import directly from _exceptions.py since this is new code with no existing
dependents on the _loader module path.

Assisted-by: Claude Sonnet 4.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Issues and PRs related to implementing Declarative Config

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants