aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py')
-rw-r--r--.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py460
1 files changed, 460 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py b/.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py
new file mode 100644
index 00000000..c1852edd
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/opentelemetry/sdk/_configuration/__init__.py
@@ -0,0 +1,460 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+OpenTelemetry SDK Configurator for Easy Instrumentation with Distros
+"""
+
+from __future__ import annotations
+
+import logging
+import os
+from abc import ABC, abstractmethod
+from os import environ
+from typing import Callable, Sequence, Type, Union
+
+from typing_extensions import Literal
+
+from opentelemetry._events import set_event_logger_provider
+from opentelemetry._logs import set_logger_provider
+from opentelemetry.environment_variables import (
+ OTEL_LOGS_EXPORTER,
+ OTEL_METRICS_EXPORTER,
+ OTEL_PYTHON_ID_GENERATOR,
+ OTEL_TRACES_EXPORTER,
+)
+from opentelemetry.metrics import set_meter_provider
+from opentelemetry.sdk._events import EventLoggerProvider
+from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
+from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, LogExporter
+from opentelemetry.sdk.environment_variables import (
+ _OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED,
+ OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
+ OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
+ OTEL_EXPORTER_OTLP_PROTOCOL,
+ OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
+ OTEL_TRACES_SAMPLER,
+ OTEL_TRACES_SAMPLER_ARG,
+)
+from opentelemetry.sdk.metrics import MeterProvider
+from opentelemetry.sdk.metrics.export import (
+ MetricExporter,
+ MetricReader,
+ PeriodicExportingMetricReader,
+)
+from opentelemetry.sdk.resources import Attributes, Resource
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter
+from opentelemetry.sdk.trace.id_generator import IdGenerator
+from opentelemetry.sdk.trace.sampling import Sampler
+from opentelemetry.semconv.resource import ResourceAttributes
+from opentelemetry.trace import set_tracer_provider
+from opentelemetry.util._importlib_metadata import entry_points
+
+_EXPORTER_OTLP = "otlp"
+_EXPORTER_OTLP_PROTO_GRPC = "otlp_proto_grpc"
+_EXPORTER_OTLP_PROTO_HTTP = "otlp_proto_http"
+
+_EXPORTER_BY_OTLP_PROTOCOL = {
+ "grpc": _EXPORTER_OTLP_PROTO_GRPC,
+ "http/protobuf": _EXPORTER_OTLP_PROTO_HTTP,
+}
+
+_EXPORTER_ENV_BY_SIGNAL_TYPE = {
+ "traces": OTEL_TRACES_EXPORTER,
+ "metrics": OTEL_METRICS_EXPORTER,
+ "logs": OTEL_LOGS_EXPORTER,
+}
+
+_PROTOCOL_ENV_BY_SIGNAL_TYPE = {
+ "traces": OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
+ "metrics": OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
+ "logs": OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
+}
+
+_RANDOM_ID_GENERATOR = "random"
+_DEFAULT_ID_GENERATOR = _RANDOM_ID_GENERATOR
+
+_OTEL_SAMPLER_ENTRY_POINT_GROUP = "opentelemetry_traces_sampler"
+
+_logger = logging.getLogger(__name__)
+
+
+def _import_config_components(
+ selected_components: list[str], entry_point_name: str
+) -> Sequence[tuple[str, object]]:
+ component_implementations = []
+
+ for selected_component in selected_components:
+ try:
+ component_implementations.append(
+ (
+ selected_component,
+ next(
+ iter(
+ entry_points(
+ group=entry_point_name, name=selected_component
+ )
+ )
+ ).load(),
+ )
+ )
+ except KeyError:
+ raise RuntimeError(
+ f"Requested entry point '{entry_point_name}' not found"
+ )
+
+ except StopIteration:
+ raise RuntimeError(
+ f"Requested component '{selected_component}' not found in "
+ f"entry point '{entry_point_name}'"
+ )
+
+ return component_implementations
+
+
+def _get_sampler() -> str | None:
+ return environ.get(OTEL_TRACES_SAMPLER, None)
+
+
+def _get_id_generator() -> str:
+ return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR)
+
+
+def _get_exporter_entry_point(
+ exporter_name: str, signal_type: Literal["traces", "metrics", "logs"]
+):
+ if exporter_name not in (
+ _EXPORTER_OTLP,
+ _EXPORTER_OTLP_PROTO_GRPC,
+ _EXPORTER_OTLP_PROTO_HTTP,
+ ):
+ return exporter_name
+
+ # Checking env vars for OTLP protocol (grpc/http).
+ otlp_protocol = environ.get(
+ _PROTOCOL_ENV_BY_SIGNAL_TYPE[signal_type]
+ ) or environ.get(OTEL_EXPORTER_OTLP_PROTOCOL)
+
+ if not otlp_protocol:
+ if exporter_name == _EXPORTER_OTLP:
+ return _EXPORTER_OTLP_PROTO_GRPC
+ return exporter_name
+
+ otlp_protocol = otlp_protocol.strip()
+
+ if exporter_name == _EXPORTER_OTLP:
+ if otlp_protocol not in _EXPORTER_BY_OTLP_PROTOCOL:
+ # Invalid value was set by the env var
+ raise RuntimeError(
+ f"Unsupported OTLP protocol '{otlp_protocol}' is configured"
+ )
+
+ return _EXPORTER_BY_OTLP_PROTOCOL[otlp_protocol]
+
+ # grpc/http already specified by exporter_name, only add a warning in case
+ # of a conflict.
+ exporter_name_by_env = _EXPORTER_BY_OTLP_PROTOCOL.get(otlp_protocol)
+ if exporter_name_by_env and exporter_name != exporter_name_by_env:
+ _logger.warning(
+ "Conflicting values for %s OTLP exporter protocol, using '%s'",
+ signal_type,
+ exporter_name,
+ )
+
+ return exporter_name
+
+
+def _get_exporter_names(
+ signal_type: Literal["traces", "metrics", "logs"],
+) -> Sequence[str]:
+ names = environ.get(_EXPORTER_ENV_BY_SIGNAL_TYPE.get(signal_type, ""))
+
+ if not names or names.lower().strip() == "none":
+ return []
+
+ return [
+ _get_exporter_entry_point(_exporter.strip(), signal_type)
+ for _exporter in names.split(",")
+ ]
+
+
+def _init_tracing(
+ exporters: dict[str, Type[SpanExporter]],
+ id_generator: IdGenerator | None = None,
+ sampler: Sampler | None = None,
+ resource: Resource | None = None,
+):
+ provider = TracerProvider(
+ id_generator=id_generator,
+ sampler=sampler,
+ resource=resource,
+ )
+ set_tracer_provider(provider)
+
+ for _, exporter_class in exporters.items():
+ exporter_args = {}
+ provider.add_span_processor(
+ BatchSpanProcessor(exporter_class(**exporter_args))
+ )
+
+
+def _init_metrics(
+ exporters_or_readers: dict[
+ str, Union[Type[MetricExporter], Type[MetricReader]]
+ ],
+ resource: Resource | None = None,
+):
+ metric_readers = []
+
+ for _, exporter_or_reader_class in exporters_or_readers.items():
+ exporter_args = {}
+
+ if issubclass(exporter_or_reader_class, MetricReader):
+ metric_readers.append(exporter_or_reader_class(**exporter_args))
+ else:
+ metric_readers.append(
+ PeriodicExportingMetricReader(
+ exporter_or_reader_class(**exporter_args)
+ )
+ )
+
+ provider = MeterProvider(resource=resource, metric_readers=metric_readers)
+ set_meter_provider(provider)
+
+
+def _init_logging(
+ exporters: dict[str, Type[LogExporter]],
+ resource: Resource | None = None,
+ setup_logging_handler: bool = True,
+):
+ provider = LoggerProvider(resource=resource)
+ set_logger_provider(provider)
+
+ for _, exporter_class in exporters.items():
+ exporter_args = {}
+ provider.add_log_record_processor(
+ BatchLogRecordProcessor(exporter_class(**exporter_args))
+ )
+
+ event_logger_provider = EventLoggerProvider(logger_provider=provider)
+ set_event_logger_provider(event_logger_provider)
+
+ if setup_logging_handler:
+ handler = LoggingHandler(
+ level=logging.NOTSET, logger_provider=provider
+ )
+ logging.getLogger().addHandler(handler)
+
+
+def _import_exporters(
+ trace_exporter_names: Sequence[str],
+ metric_exporter_names: Sequence[str],
+ log_exporter_names: Sequence[str],
+) -> tuple[
+ dict[str, Type[SpanExporter]],
+ dict[str, Union[Type[MetricExporter], Type[MetricReader]]],
+ dict[str, Type[LogExporter]],
+]:
+ trace_exporters = {}
+ metric_exporters = {}
+ log_exporters = {}
+
+ for (
+ exporter_name,
+ exporter_impl,
+ ) in _import_config_components(
+ trace_exporter_names, "opentelemetry_traces_exporter"
+ ):
+ if issubclass(exporter_impl, SpanExporter):
+ trace_exporters[exporter_name] = exporter_impl
+ else:
+ raise RuntimeError(f"{exporter_name} is not a trace exporter")
+
+ for (
+ exporter_name,
+ exporter_impl,
+ ) in _import_config_components(
+ metric_exporter_names, "opentelemetry_metrics_exporter"
+ ):
+ # The metric exporter components may be push MetricExporter or pull exporters which
+ # subclass MetricReader directly
+ if issubclass(exporter_impl, (MetricExporter, MetricReader)):
+ metric_exporters[exporter_name] = exporter_impl
+ else:
+ raise RuntimeError(f"{exporter_name} is not a metric exporter")
+
+ for (
+ exporter_name,
+ exporter_impl,
+ ) in _import_config_components(
+ log_exporter_names, "opentelemetry_logs_exporter"
+ ):
+ if issubclass(exporter_impl, LogExporter):
+ log_exporters[exporter_name] = exporter_impl
+ else:
+ raise RuntimeError(f"{exporter_name} is not a log exporter")
+
+ return trace_exporters, metric_exporters, log_exporters
+
+
+def _import_sampler_factory(sampler_name: str) -> Callable[[str], Sampler]:
+ _, sampler_impl = _import_config_components(
+ [sampler_name.strip()], _OTEL_SAMPLER_ENTRY_POINT_GROUP
+ )[0]
+ return sampler_impl
+
+
+def _import_sampler(sampler_name: str) -> Sampler | None:
+ if not sampler_name:
+ return None
+ try:
+ sampler_factory = _import_sampler_factory(sampler_name)
+ arg = None
+ if sampler_name in ("traceidratio", "parentbased_traceidratio"):
+ try:
+ rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG))
+ except (ValueError, TypeError):
+ _logger.warning(
+ "Could not convert TRACES_SAMPLER_ARG to float. Using default value 1.0."
+ )
+ rate = 1.0
+ arg = rate
+ else:
+ arg = os.getenv(OTEL_TRACES_SAMPLER_ARG)
+
+ sampler = sampler_factory(arg)
+ if not isinstance(sampler, Sampler):
+ message = f"Sampler factory, {sampler_factory}, produced output, {sampler}, which is not a Sampler."
+ _logger.warning(message)
+ raise ValueError(message)
+ return sampler
+ except Exception as exc: # pylint: disable=broad-exception-caught
+ _logger.warning(
+ "Using default sampler. Failed to initialize sampler, %s: %s",
+ sampler_name,
+ exc,
+ )
+ return None
+
+
+def _import_id_generator(id_generator_name: str) -> IdGenerator:
+ id_generator_name, id_generator_impl = _import_config_components(
+ [id_generator_name.strip()], "opentelemetry_id_generator"
+ )[0]
+
+ if issubclass(id_generator_impl, IdGenerator):
+ return id_generator_impl()
+
+ raise RuntimeError(f"{id_generator_name} is not an IdGenerator")
+
+
+def _initialize_components(
+ auto_instrumentation_version: str | None = None,
+ trace_exporter_names: list[str] | None = None,
+ metric_exporter_names: list[str] | None = None,
+ log_exporter_names: list[str] | None = None,
+ sampler: Sampler | None = None,
+ resource_attributes: Attributes | None = None,
+ id_generator: IdGenerator | None = None,
+ setup_logging_handler: bool | None = None,
+):
+ if trace_exporter_names is None:
+ trace_exporter_names = []
+ if metric_exporter_names is None:
+ metric_exporter_names = []
+ if log_exporter_names is None:
+ log_exporter_names = []
+ span_exporters, metric_exporters, log_exporters = _import_exporters(
+ trace_exporter_names + _get_exporter_names("traces"),
+ metric_exporter_names + _get_exporter_names("metrics"),
+ log_exporter_names + _get_exporter_names("logs"),
+ )
+ if sampler is None:
+ sampler_name = _get_sampler()
+ sampler = _import_sampler(sampler_name)
+ if id_generator is None:
+ id_generator_name = _get_id_generator()
+ id_generator = _import_id_generator(id_generator_name)
+ if resource_attributes is None:
+ resource_attributes = {}
+ # populate version if using auto-instrumentation
+ if auto_instrumentation_version:
+ resource_attributes[ResourceAttributes.TELEMETRY_AUTO_VERSION] = (
+ auto_instrumentation_version
+ )
+ # if env var OTEL_RESOURCE_ATTRIBUTES is given, it will read the service_name
+ # from the env variable else defaults to "unknown_service"
+ resource = Resource.create(resource_attributes)
+
+ _init_tracing(
+ exporters=span_exporters,
+ id_generator=id_generator,
+ sampler=sampler,
+ resource=resource,
+ )
+ _init_metrics(metric_exporters, resource)
+ if setup_logging_handler is None:
+ setup_logging_handler = (
+ os.getenv(
+ _OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "false"
+ )
+ .strip()
+ .lower()
+ == "true"
+ )
+ _init_logging(log_exporters, resource, setup_logging_handler)
+
+
+class _BaseConfigurator(ABC):
+ """An ABC for configurators
+
+ Configurators are used to configure
+ SDKs (i.e. TracerProvider, MeterProvider, Processors...)
+ to reduce the amount of manual configuration required.
+ """
+
+ _instance = None
+ _is_instrumented = False
+
+ def __new__(cls, *args, **kwargs):
+ if cls._instance is None:
+ cls._instance = object.__new__(cls, *args, **kwargs)
+
+ return cls._instance
+
+ @abstractmethod
+ def _configure(self, **kwargs):
+ """Configure the SDK"""
+
+ def configure(self, **kwargs):
+ """Configure the SDK"""
+ self._configure(**kwargs)
+
+
+class _OTelSDKConfigurator(_BaseConfigurator):
+ """A basic Configurator by OTel Python for initializing OTel SDK components
+
+ Initializes several crucial OTel SDK components (i.e. TracerProvider,
+ MeterProvider, Processors...) according to a default implementation. Other
+ Configurators can subclass and slightly alter this initialization.
+
+ NOTE: This class should not be instantiated nor should it become an entry
+ point on the `opentelemetry-sdk` package. Instead, distros should subclass
+ this Configurator and enhance it as needed.
+ """
+
+ def _configure(self, **kwargs):
+ _initialize_components(**kwargs)