Skip to content

Commit 1e68c3c

Browse files
committed
Initial Commit
1 parent 14401e1 commit 1e68c3c

File tree

3 files changed

+163
-6
lines changed

3 files changed

+163
-6
lines changed

opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py

Lines changed: 124 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
from __future__ import annotations
2121

22+
import inspect
2223
import logging
2324
import os
2425
from abc import ABC, abstractmethod
2526
from os import environ
26-
from typing import Any, Callable, Mapping, Sequence, Type, Union
27+
from typing import Any, Callable, Mapping, Optional, Sequence, Type, Union
2728

29+
from grpc import ChannelCredentials # pylint: disable=import-error
30+
from requests import Session
2831
from typing_extensions import Literal
2932

3033
from opentelemetry._events import set_event_logger_provider
@@ -45,6 +48,10 @@
4548
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
4649
OTEL_EXPORTER_OTLP_PROTOCOL,
4750
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
51+
OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER,
52+
OTEL_PYTHON_EXPORTER_OTLP_LOGS_CREDENTIAL_PROVIDER,
53+
OTEL_PYTHON_EXPORTER_OTLP_METRICS_CREDENTIAL_PROVIDER,
54+
OTEL_PYTHON_EXPORTER_OTLP_TRACES_CREDENTIAL_PROVIDER,
4855
OTEL_TRACES_SAMPLER,
4956
OTEL_TRACES_SAMPLER_ARG,
5057
)
@@ -78,6 +85,12 @@
7885
"logs": OTEL_LOGS_EXPORTER,
7986
}
8087

88+
_EXPORTER_CREDENTIAL_BY_SIGNAL_TYPE = {
89+
"traces": OTEL_PYTHON_EXPORTER_OTLP_TRACES_CREDENTIAL_PROVIDER,
90+
"metrics": OTEL_PYTHON_EXPORTER_OTLP_METRICS_CREDENTIAL_PROVIDER,
91+
"logs": OTEL_PYTHON_EXPORTER_OTLP_LOGS_CREDENTIAL_PROVIDER,
92+
}
93+
8194
_PROTOCOL_ENV_BY_SIGNAL_TYPE = {
8295
"traces": OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
8396
"metrics": OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
@@ -102,6 +115,36 @@
102115
]
103116

104117

118+
def _load_credential_from_envvar(
119+
environment_variable: str,
120+
) -> Optional[
121+
tuple[
122+
Literal["credentials", "session"], Union[ChannelCredentials, Session]
123+
]
124+
]:
125+
credential_env = os.getenv(environment_variable)
126+
if credential_env:
127+
credentials = _import_config_component(
128+
credential_env, "opentelemetry_otlp_credential_provider"
129+
)()
130+
if isinstance(credentials, ChannelCredentials):
131+
return ("credentials", credentials)
132+
elif isinstance(credentials, Session):
133+
return ("session", credentials)
134+
else:
135+
raise RuntimeError(
136+
f"{credential_env} is neither a ChannelCredentials or Session type."
137+
)
138+
139+
140+
def _import_config_component(
141+
selected_component: str, entry_point_name: str
142+
) -> Type:
143+
return _import_config_components([selected_component], entry_point_name)[
144+
0
145+
][1]
146+
147+
105148
def _import_config_components(
106149
selected_components: Sequence[str], entry_point_name: str
107150
) -> list[tuple[str, Type]]:
@@ -201,12 +244,54 @@ def _get_exporter_names(
201244
]
202245

203246

247+
def _init_exporter(
248+
signal_type: Literal["traces", "metrics", "logs"],
249+
exporter_args_map: Mapping[str, Any],
250+
exporter_class: Union[
251+
Type[SpanExporter], Type[MetricExporter], Type[LogExporter]
252+
],
253+
otlp_credential_param_for_all_signal_types: Optional[
254+
tuple[
255+
Literal["credentials", "session"],
256+
Union[ChannelCredentials, Session],
257+
]
258+
] = None,
259+
) -> Union[SpanExporter, MetricExporter, LogExporter]:
260+
otlp_credential_param_for_signal_type = _load_credential_from_envvar(
261+
_EXPORTER_CREDENTIAL_BY_SIGNAL_TYPE[signal_type]
262+
)
263+
otlp_credential_param = (
264+
otlp_credential_param_for_signal_type
265+
or otlp_credential_param_for_all_signal_types
266+
)
267+
if not otlp_credential_param:
268+
return exporter_class(**exporter_args_map)
269+
credential_key, credential = otlp_credential_param
270+
params = inspect.signature(exporter_class.__init__).parameters
271+
if (
272+
credential_key == "credentials"
273+
and "credentials" in params
274+
and isinstance(credential, params["credentials"].annotation)
275+
):
276+
return exporter_class(credentials=credential, **exporter_args_map)
277+
if (
278+
credential_key == "session"
279+
and "session" in params
280+
and isinstance(credential, params["session"].annotation)
281+
):
282+
return exporter_class(session=credential, **exporter_args_map)
283+
return exporter_class(**exporter_args_map)
284+
285+
204286
def _init_tracing(
205287
exporters: dict[str, Type[SpanExporter]],
206288
id_generator: IdGenerator | None = None,
207289
sampler: Sampler | None = None,
208290
resource: Resource | None = None,
209291
exporter_args_map: ExporterArgsMap | None = None,
292+
otlp_credential_param: Optional[
293+
tuple[str, Union[ChannelCredentials, Session]]
294+
] = None,
210295
):
211296
provider = TracerProvider(
212297
id_generator=id_generator,
@@ -219,16 +304,26 @@ def _init_tracing(
219304
for _, exporter_class in exporters.items():
220305
exporter_args = exporter_args_map.get(exporter_class, {})
221306
provider.add_span_processor(
222-
BatchSpanProcessor(exporter_class(**exporter_args))
307+
BatchSpanProcessor(
308+
_init_exporter(
309+
"traces",
310+
exporter_args,
311+
exporter_class,
312+
otlp_credential_param,
313+
)
314+
)
223315
)
224316

225317

226318
def _init_metrics(
227319
exporters_or_readers: dict[
228320
str, Union[Type[MetricExporter], Type[MetricReader]]
229321
],
230-
resource: Resource | None = None,
322+
resource: Resource = None,
231323
exporter_args_map: ExporterArgsMap | None = None,
324+
otlp_credential_param: Optional[
325+
tuple[str, Union[ChannelCredentials, Session]]
326+
] = None,
232327
):
233328
metric_readers = []
234329

@@ -240,7 +335,12 @@ def _init_metrics(
240335
else:
241336
metric_readers.append(
242337
PeriodicExportingMetricReader(
243-
exporter_or_reader_class(**exporter_args)
338+
_init_exporter(
339+
"metrics",
340+
exporter_args,
341+
exporter_or_reader_class,
342+
otlp_credential_param,
343+
)
244344
)
245345
)
246346

@@ -253,6 +353,9 @@ def _init_logging(
253353
resource: Resource | None = None,
254354
setup_logging_handler: bool = True,
255355
exporter_args_map: ExporterArgsMap | None = None,
356+
otlp_credential_param: Optional[
357+
tuple[str, Union[ChannelCredentials, Session]]
358+
] = None,
256359
):
257360
provider = LoggerProvider(resource=resource)
258361
set_logger_provider(provider)
@@ -261,7 +364,14 @@ def _init_logging(
261364
for _, exporter_class in exporters.items():
262365
exporter_args = exporter_args_map.get(exporter_class, {})
263366
provider.add_log_record_processor(
264-
BatchLogRecordProcessor(exporter_class(**exporter_args))
367+
BatchLogRecordProcessor(
368+
_init_exporter(
369+
"logs",
370+
exporter_args,
371+
exporter_class,
372+
otlp_credential_param,
373+
)
374+
)
265375
)
266376

267377
event_logger_provider = EventLoggerProvider(logger_provider=provider)
@@ -438,15 +548,22 @@ def _initialize_components(
438548
# from the env variable else defaults to "unknown_service"
439549
resource = Resource.create(resource_attributes)
440550

551+
otlp_credential_param = _load_credential_from_envvar(
552+
OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER
553+
)
441554
_init_tracing(
442555
exporters=span_exporters,
443556
id_generator=id_generator,
444557
sampler=sampler,
445558
resource=resource,
559+
otlp_credential_param=otlp_credential_param,
446560
exporter_args_map=exporter_args_map,
447561
)
448562
_init_metrics(
449-
metric_exporters, resource, exporter_args_map=exporter_args_map
563+
metric_exporters,
564+
resource,
565+
otlp_credential_param=otlp_credential_param,
566+
exporter_args_map=exporter_args_map,
450567
)
451568
if setup_logging_handler is None:
452569
setup_logging_handler = (
@@ -461,6 +578,7 @@ def _initialize_components(
461578
log_exporters,
462579
resource,
463580
setup_logging_handler,
581+
otlp_credential_param=otlp_credential_param,
464582
exporter_args_map=exporter_args_map,
465583
)
466584

opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/__init__.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,43 @@
394394
A scheme of https indicates a secure connection and takes precedence over this configuration setting.
395395
"""
396396

397+
OTEL_PYTHON_EXPORTER_OTLP_LOGS_CREDENTIAL_PROVIDER = (
398+
"OTEL_PYTHON_EXPORTER_OTLP_LOGS_CREDENTIAL_PROVIDER"
399+
)
400+
"""
401+
.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER
402+
403+
The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_LOGS_CREDENTIAL_PROVIDER` provides either ChannelCredentials for grpc OTLP Log exporters,
404+
or request.Session for HTTP Log exporters.
405+
"""
406+
OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER = (
407+
"OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER"
408+
)
409+
"""
410+
.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER
411+
412+
The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER` provides either ChannelCredentials for all grpc OTLP exporters,
413+
or request.Session for HTTP exporters.
414+
"""
415+
OTEL_PYTHON_EXPORTER_OTLP_TRACES_CREDENTIAL_PROVIDER = (
416+
"OTEL_PYTHON_EXPORTER_OTLP_TRACES_CREDENTIAL_PROVIDER"
417+
)
418+
"""
419+
.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER
420+
421+
The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_TRACES_CREDENTIAL_PROVIDER` provides either ChannelCredentials for grpc OTLP Span exporters,
422+
or request.Session for HTTP Span exporters.
423+
"""
424+
OTEL_PYTHON_EXPORTER_OTLP_METRICS_CREDENTIAL_PROVIDER = (
425+
"OTEL_PYTHON_EXPORTER_OTLP_METRICS_CREDENTIAL_PROVIDER"
426+
)
427+
"""
428+
.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_CREDENTIAL_PROVIDER
429+
430+
The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_METRICS_CREDENTIAL_PROVIDER` provides either ChannelCredentials for grpc OTLP Metric exporters,
431+
or request.Session for HTTP Metric exporters.
432+
"""
433+
397434
OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE"
398435
"""
399436
.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE

opentelemetry-sdk/test-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ py-cpuinfo==9.0.0
99
pytest==7.4.4
1010
tomli==2.0.1
1111
typing_extensions==4.10.0
12+
grpcio==1.66.2
13+
requests==2.32.3
1214
wrapt==1.16.0
1315
zipp==3.19.2
1416
-e tests/opentelemetry-test-utils

0 commit comments

Comments
 (0)