Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changelog/5390.added
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
`opentelemetry-configuration`: wire the experimental
`tracer_configurator/development`, `meter_configurator/development` and
`logger_configurator/development` fields into `create_tracer_provider`,
`create_meter_provider` and `create_logger_provider`, so per-instrumentation-scope
`enabled` overrides declared in the config file are applied to the provider
(previously these fields were parsed but silently discarded). The logger
`minimum_severity`/`trace_based` fields are not supported by the Python SDK and
are ignored with a warning.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
from opentelemetry.configuration.models import (
BatchLogRecordProcessor as BatchLogRecordProcessorConfig,
)
from opentelemetry.configuration.models import (
ExperimentalLoggerConfig as LoggerConfigConfig,
)
from opentelemetry.configuration.models import (
ExperimentalLoggerConfigurator as LoggerConfiguratorConfig,
)
from opentelemetry.configuration.models import (
ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig,
)
Expand All @@ -41,13 +47,18 @@
SimpleLogRecordProcessor as SimpleLogRecordProcessorConfig,
)
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs._internal import (
_LoggerConfig,
_RuleBasedLoggerConfigurator,
)
from opentelemetry.sdk._logs._internal.export import (
BatchLogRecordProcessor,
ConsoleLogRecordExporter,
LogRecordExporter,
SimpleLogRecordProcessor,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -235,6 +246,49 @@ def _create_log_record_processor(
)


def _to_logger_config(config: LoggerConfigConfig | None) -> _LoggerConfig:
"""Map an experimental per-logger config to an SDK ``_LoggerConfig``.

Only ``enabled`` is honored. ``minimum_severity`` and ``trace_based`` are
accepted by the config schema but not supported by the Python SDK
``_LoggerConfig``; when set, they are ignored with a warning. An absent
``enabled`` leaves the logger enabled.
"""
if config is None:
return _LoggerConfig.default()
if config.minimum_severity is not None or config.trace_based is not None:
_logger.warning(
"logger_configurator minimum_severity/trace_based are specified in "
"config but are not supported by the Python SDK LoggerProvider; "
"they will be ignored."
)
if config.enabled is None:
return _LoggerConfig.default()
return _LoggerConfig(is_enabled=config.enabled)


def _create_logger_configurator(
config: LoggerConfiguratorConfig,
) -> _RuleBasedLoggerConfigurator:
"""Build a rule-based logger configurator from experimental config.

Each entry in ``loggers`` maps an instrumentation-scope name glob to a
per-logger config; ``default_config`` applies to scopes matching no glob.
Rules are evaluated in order, so earlier entries take precedence.
"""
rules = [
(
_scope_name_matches_glob(matcher.name),
_to_logger_config(matcher.config),
)
for matcher in (config.loggers or [])
]
return _RuleBasedLoggerConfigurator(
rules=rules,
default_config=_to_logger_config(config.default_config),
)


def create_logger_provider(
config: LoggerProviderConfig | None,
resource: Resource | None = None,
Expand All @@ -251,7 +305,16 @@ def create_logger_provider(
Returns:
A configured LoggerProvider.
"""
provider = LoggerProvider(resource=resource)
logger_configurator = (
_create_logger_configurator(config.logger_configurator_development)
if config is not None
and config.logger_configurator_development is not None
else None
)

provider = LoggerProvider(
resource=resource, _logger_configurator=logger_configurator
)

if config is None:
return provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
from opentelemetry.configuration.models import (
ExemplarFilter as ExemplarFilterConfig,
)
from opentelemetry.configuration.models import (
ExperimentalMeterConfig as MeterConfigConfig,
)
from opentelemetry.configuration.models import (
ExperimentalMeterConfigurator as MeterConfiguratorConfig,
)
from opentelemetry.configuration.models import (
ExperimentalOtlpFileMetricExporter as ExperimentalOtlpFileMetricExporterConfig,
)
Expand Down Expand Up @@ -76,6 +82,10 @@
UpDownCounter,
_Gauge,
)
from opentelemetry.sdk.metrics._internal import (
_MeterConfig,
_RuleBasedMeterConfigurator,
)
from opentelemetry.sdk.metrics.export import (
AggregationTemporality,
ConsoleMetricExporter,
Expand All @@ -94,6 +104,7 @@
View,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -567,6 +578,39 @@ def _create_exemplar_filter(
)


def _to_meter_config(config: MeterConfigConfig | None) -> _MeterConfig:
"""Map an experimental per-meter config to an SDK ``_MeterConfig``.

Only ``enabled`` is honored — it is the sole field the SDK
``_MeterConfig`` exposes. An absent ``enabled`` leaves the meter enabled.
"""
if config is None or config.enabled is None:
return _MeterConfig.default()
return _MeterConfig(is_enabled=config.enabled)


def _create_meter_configurator(
config: MeterConfiguratorConfig,
) -> _RuleBasedMeterConfigurator:
"""Build a rule-based meter configurator from experimental config.

Each entry in ``meters`` maps an instrumentation-scope name glob to a
per-meter config; ``default_config`` applies to scopes matching no glob.
Rules are evaluated in order, so earlier entries take precedence.
"""
rules = [
(
_scope_name_matches_glob(matcher.name),
_to_meter_config(matcher.config),
)
for matcher in (config.meters or [])
]
return _RuleBasedMeterConfigurator(
rules=rules,
default_config=_to_meter_config(config.default_config),
)


def create_meter_provider(
config: MeterProviderConfig | None,
resource: Resource | None = None,
Expand Down Expand Up @@ -600,11 +644,19 @@ def create_meter_provider(
for view_config in config.views:
views.append(_create_view(view_config))

meter_configurator = (
_create_meter_configurator(config.meter_configurator_development)
if config is not None
and config.meter_configurator_development is not None
else None
)

return MeterProvider(
resource=resource,
metric_readers=readers,
exemplar_filter=exemplar_filter, # type: ignore[arg-type]
views=views,
_meter_configurator=meter_configurator,
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
from opentelemetry.configuration.models import (
ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig,
)
from opentelemetry.configuration.models import (
ExperimentalTracerConfig as TracerConfigConfig,
)
from opentelemetry.configuration.models import (
ExperimentalTracerConfigurator as TracerConfiguratorConfig,
)
from opentelemetry.configuration.models import (
IdGenerator as IdGeneratorConfig,
)
Expand Down Expand Up @@ -64,6 +70,8 @@
_DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT,
SpanLimits,
TracerProvider,
_RuleBasedTracerConfigurator,
_TracerConfig,
)
from opentelemetry.sdk.trace._sampling_experimental import (
ComposableSampler,
Expand Down Expand Up @@ -98,6 +106,7 @@
Sampler,
TraceIdRatioBased,
)
from opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob
from opentelemetry.trace import SpanKind as TraceSpanKind

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -436,6 +445,39 @@ def _create_span_limits(config: SpanLimitsConfig) -> SpanLimits:
)


def _to_tracer_config(config: TracerConfigConfig | None) -> _TracerConfig:
"""Map an experimental per-tracer config to an SDK ``_TracerConfig``.

Only ``enabled`` is honored — it is the sole field the SDK
``_TracerConfig`` exposes. An absent ``enabled`` leaves the tracer enabled.
"""
if config is None or config.enabled is None:
return _TracerConfig.default()
return _TracerConfig(is_enabled=config.enabled)


def _create_tracer_configurator(
config: TracerConfiguratorConfig,
) -> _RuleBasedTracerConfigurator:
"""Build a rule-based tracer configurator from experimental config.

Each entry in ``tracers`` maps an instrumentation-scope name glob to a
per-tracer config; ``default_config`` applies to scopes matching no glob.
Rules are evaluated in order, so earlier entries take precedence.
"""
rules = [
(
_scope_name_matches_glob(matcher.name),
_to_tracer_config(matcher.config),
)
for matcher in (config.tracers or [])
]
return _RuleBasedTracerConfigurator(
rules=rules,
default_config=_to_tracer_config(config.default_config),
)


def create_tracer_provider(
config: TracerProviderConfig | None,
resource: Resource | None = None,
Expand Down Expand Up @@ -475,11 +517,19 @@ def create_tracer_provider(
)
)

tracer_configurator = (
_create_tracer_configurator(config.tracer_configurator_development)
if config is not None
and config.tracer_configurator_development is not None
else None
)

provider = TracerProvider(
resource=resource,
sampler=sampler,
span_limits=span_limits,
id_generator=id_generator,
_tracer_configurator=tracer_configurator,
)

if config is not None:
Expand Down
Loading
Loading