-
Notifications
You must be signed in to change notification settings - Fork 646
/
__init__.py
167 lines (134 loc) · 5.57 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# 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.
"""
API for propagation of context.
The propagators for the
``opentelemetry.propagators.composite.CompositePropagator`` can be defined
via configuration in the ``OTEL_PROPAGATORS`` environment variable. This
variable should be set to a comma-separated string of names of values for the
``opentelemetry_propagator`` entry point. For example, setting
``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value)
would instantiate
``opentelemetry.propagators.composite.CompositePropagator`` with 2
propagators, one of type
``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator``
and other of type ``opentelemetry.baggage.propagation.W3CBaggagePropagator``.
Notice that these propagator classes are defined as
``opentelemetry_propagator`` entry points in the ``pyproject.toml`` file of
``opentelemetry``.
Example::
import flask
import requests
from opentelemetry import propagate
PROPAGATOR = propagate.get_global_textmap()
def get_header_from_flask_request(request, key):
return request.headers.get_all(key)
def set_header_into_requests_request(request: requests.Request,
key: str, value: str):
request.headers[key] = value
def example_route():
context = PROPAGATOR.extract(
get_header_from_flask_request,
flask.request
)
request_to_downstream = requests.Request(
"GET", "http://httpbin.org/get"
)
PROPAGATOR.inject(
set_header_into_requests_request,
request_to_downstream,
context=context
)
session = requests.Session()
session.send(request_to_downstream.prepare())
.. _Propagation API Specification:
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md
"""
from logging import getLogger
from os import environ
from typing import Optional
from opentelemetry.context.context import Context
from opentelemetry.environment_variables import OTEL_PROPAGATORS
from opentelemetry.propagators import composite, textmap
from opentelemetry.util._importlib_metadata import entry_points
logger = getLogger(__name__)
def extract(
carrier: textmap.CarrierT,
context: Optional[Context] = None,
getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter,
) -> Context:
"""Uses the configured propagator to extract a Context from the carrier.
Args:
getter: an object which contains a get function that can retrieve zero
or more values from the carrier and a keys function that can get all the keys
from carrier.
carrier: and object which contains values that are
used to construct a Context. This object
must be paired with an appropriate getter
which understands how to extract a value from it.
context: an optional Context to use. Defaults to root
context if not set.
"""
return get_global_textmap().extract(carrier, context, getter=getter)
def inject(
carrier: textmap.CarrierT,
context: Optional[Context] = None,
setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter,
) -> None:
"""Uses the configured propagator to inject a Context into the carrier.
Args:
carrier: the medium used by Propagators to read
values from and write values to.
Should be paired with setter, which
should know how to set header values on the carrier.
context: An optional Context to use. Defaults to current
context if not set.
setter: An optional `Setter` object that can set values
on the carrier.
"""
get_global_textmap().inject(carrier, context=context, setter=setter)
propagators = []
# Single use variable here to hack black and make lint pass
environ_propagators = environ.get(
OTEL_PROPAGATORS,
"tracecontext,baggage",
)
for propagator in environ_propagators.split(","):
propagator = propagator.strip()
try:
propagators.append( # type: ignore
next( # type: ignore
iter( # type: ignore
entry_points( # type: ignore
group="opentelemetry_propagator",
name=propagator,
)
)
).load()()
)
except StopIteration:
raise ValueError(
f"Propagator {propagator} not found. It is either misspelled or not installed."
)
except Exception: # pylint: disable=broad-exception-caught
logger.exception("Failed to load propagator: %s", propagator)
raise
_HTTP_TEXT_FORMAT = composite.CompositePropagator(propagators) # type: ignore
def get_global_textmap() -> textmap.TextMapPropagator:
return _HTTP_TEXT_FORMAT
def set_global_textmap(
http_text_format: textmap.TextMapPropagator,
) -> None:
global _HTTP_TEXT_FORMAT # pylint:disable=global-statement
_HTTP_TEXT_FORMAT = http_text_format # type: ignore