open-telemetry / open-telemetry/opentelemetry-python

feat(config): unify declarative and env-var configuration through a shared SDK orchestrator

Open
#5,126 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Motivation

Today there are two independent configuration paths that construct the SDK:

  1. Env-var path_initialize_components() in opentelemetry/sdk/_configuration/__init__.py orchestrates SDK init, but env-var reading is scattered across individual SDK classes (TracerProvider, BatchSpanProcessor, Resource, MeterProvider, sampling, etc.). Each class reads its own OTEL_* vars at construction time.

  2. Declarative file path — modular create_*/configure_* factory functions per signal (_tracer_provider.py, _logger_provider.py, _meter_provider.py, _propagator.py, _resource.py), but no top-level orchestrator that ties them together.

This split means:

  • Env-var reading logic is duplicated or scattered, making it hard to maintain
  • There's no single "apply this config" entry point for the declarative path
  • The two paths can drift in behavior since they don't share construction logic

Proposal

1. Add a top-level configure_sdk(config) orchestrator

A single function that takes an OpenTelemetryConfiguration and calls all configure_* functions in the correct order:

def configure_sdk(config: OpenTelemetryConfiguration) -> None:
    resource = create_resource(config.resource)
    configure_tracer_provider(config.tracer_provider, resource)
    configure_meter_provider(config.meter_provider, resource)
    configure_logger_provider(config.logger_provider, resource)
    configure_propagator(config.propagator)
2. Add an env-var-to-config adapter

A function that reads all OTEL_* env vars and produces an OpenTelemetryConfiguration, which then flows through the same configure_sdk() path:

def load_config_from_env() -> OpenTelemetryConfiguration:
    """Read OTEL_* env vars and build an OpenTelemetryConfiguration."""
    ...
End state
YAML file → load_config_file() → OpenTelemetryConfiguration → configure_sdk()
env vars  → load_config_env()  → OpenTelemetryConfiguration → configure_sdk()

Both paths converge on the same construction logic, eliminating drift.

Considerations

  • Scattered env-var reads in constructors: BatchSpanProcessor.__init__, TracerProvider.__init__, etc. read env vars when no explicit value is passed. Changing this touches public API surface and needs careful deprecation.
  • Spec requirement: Individual components must respect env vars when no explicit config value is provided. A pure "read everything upfront" approach needs to distinguish "not configured" from "explicitly set to default".
  • Backwards compatibility: The existing _OTelSDKConfigurator / _BaseConfigurator pattern is used by distros. Any refactor needs to preserve that extension point.
  • Scope: This is a large refactor best done incrementally — start with configure_sdk() for the declarative path, then gradually migrate env-var reading.

Related

  • #3631 — declarative config tracking issue

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with _initialize_components() in opentelemetry/sdk/_configuration/init.py and the signal-specific _tracer_provider.py, _logger_provider.py, _meter_provider.py, _propagator.py, and _resource.py factories. Trace the existing _OTelSDKConfigurator and _BaseConfigurator extension points before defining the incremental scope. Done means the declarative path has a shared configure_sdk() entry point while preserving existing constructor behavior and distro compatibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.