Skip to content

Commit f3d5897

Browse files
committed
Sync with Remove setters and getters
Fixes #issue_371
1 parent f8e51c4 commit f3d5897

File tree

29 files changed

+168
-356
lines changed

29 files changed

+168
-356
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- 'release/*'
77
pull_request:
88
env:
9-
CORE_REPO_SHA: d3694fc520f8542b232fd1065133286f4591dcec
9+
CORE_REPO_SHA: cfd4dc7f683792743c41a7e501becce8779d212a
1010

1111
jobs:
1212
build:

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased](https://github.com/open-telemetry/opentelemetry-python-contrib/compare/v0.18b0...HEAD)
8+
- Remove getters and setters from propagators
9+
([#372](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/364))
810
- Updated instrumentations to use `opentelemetry.trace.use_span` instead of `Tracer.use_span()`
911
([#364](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/364))
1012

docs/nitpick-exceptions.ini

-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,10 @@
22
class_references=
33
; TODO: Understand why sphinx is not able to find this local class
44
opentelemetry.propagators.textmap.TextMapPropagator
5-
; - AwsXRayFormat
6-
opentelemetry.propagators.textmap.DictGetter
7-
; API
8-
opentelemetry.propagators.textmap.Getter
95
; - DatadogFormat
106
; - AWSXRayFormat
117
opentelemetry.sdk.trace.id_generator.IdGenerator
128
; - AwsXRayIdGenerator
13-
TextMapPropagatorT
149
; - AwsXRayFormat.extract
1510

1611
anys=

exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py

+15-48
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import typing
15+
from typing import Dict, Optional
1616

1717
from opentelemetry import trace
1818
from opentelemetry.context import Context
1919
from opentelemetry.exporter.datadog import constants
20-
from opentelemetry.propagators.textmap import (
21-
Getter,
22-
Setter,
23-
TextMapPropagator,
24-
TextMapPropagatorT,
25-
)
20+
from opentelemetry.propagators.textmap import TextMapPropagator
2621
from opentelemetry.trace import get_current_span, set_span_in_context
2722

2823

@@ -35,24 +30,15 @@ class DatadogFormat(TextMapPropagator):
3530
ORIGIN_KEY = "x-datadog-origin"
3631

3732
def extract(
38-
self,
39-
getter: Getter[TextMapPropagatorT],
40-
carrier: TextMapPropagatorT,
41-
context: typing.Optional[Context] = None,
33+
self, carrier: Dict[str, str], context: Optional[Context] = None,
4234
) -> Context:
43-
trace_id = extract_first_element(
44-
getter.get(carrier, self.TRACE_ID_KEY)
45-
)
35+
trace_id = carrier.get(self.TRACE_ID_KEY)
4636

47-
span_id = extract_first_element(
48-
getter.get(carrier, self.PARENT_ID_KEY)
49-
)
37+
span_id = carrier.get(self.PARENT_ID_KEY)
5038

51-
sampled = extract_first_element(
52-
getter.get(carrier, self.SAMPLING_PRIORITY_KEY)
53-
)
39+
sampled = carrier.get(self.SAMPLING_PRIORITY_KEY)
5440

55-
origin = extract_first_element(getter.get(carrier, self.ORIGIN_KEY))
41+
origin = carrier.get(self.ORIGIN_KEY)
5642

5743
trace_flags = trace.TraceFlags()
5844
if sampled and int(sampled) in (
@@ -80,33 +66,22 @@ def extract(
8066
)
8167

8268
def inject(
83-
self,
84-
set_in_carrier: Setter[TextMapPropagatorT],
85-
carrier: TextMapPropagatorT,
86-
context: typing.Optional[Context] = None,
69+
self, carrier: Dict[str, str], context: Optional[Context] = None,
8770
) -> None:
8871
span = get_current_span(context)
8972
span_context = span.get_span_context()
9073
if span_context == trace.INVALID_SPAN_CONTEXT:
9174
return
9275
sampled = (trace.TraceFlags.SAMPLED & span.context.trace_flags) != 0
93-
set_in_carrier(
94-
carrier, self.TRACE_ID_KEY, format_trace_id(span.context.trace_id),
95-
)
96-
set_in_carrier(
97-
carrier, self.PARENT_ID_KEY, format_span_id(span.context.span_id)
98-
)
99-
set_in_carrier(
100-
carrier,
101-
self.SAMPLING_PRIORITY_KEY,
102-
str(constants.AUTO_KEEP if sampled else constants.AUTO_REJECT),
76+
carrier[self.TRACE_ID_KEY] = format_trace_id(span.context.trace_id)
77+
carrier[self.PARENT_ID_KEY] = format_span_id(span.context.span_id)
78+
carrier[self.SAMPLING_PRIORITY_KEY] = str(
79+
constants.AUTO_KEEP if sampled else constants.AUTO_REJECT
10380
)
10481
if constants.DD_ORIGIN in span.context.trace_state:
105-
set_in_carrier(
106-
carrier,
107-
self.ORIGIN_KEY,
108-
span.context.trace_state[constants.DD_ORIGIN],
109-
)
82+
carrier[self.ORIGIN_KEY] = span.context.trace_state[
83+
constants.DD_ORIGIN
84+
]
11085

11186
@property
11287
def fields(self):
@@ -131,11 +106,3 @@ def format_trace_id(trace_id: int) -> str:
131106
def format_span_id(span_id: int) -> str:
132107
"""Format the span id for Datadog."""
133108
return str(span_id)
134-
135-
136-
def extract_first_element(
137-
items: typing.Iterable[TextMapPropagatorT],
138-
) -> typing.Optional[TextMapPropagatorT]:
139-
if items is None:
140-
return None
141-
return next(iter(items), None)

exporter/opentelemetry-exporter-datadog/tests/test_datadog_format.py

+8-19
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@
1717

1818
from opentelemetry import trace as trace_api
1919
from opentelemetry.exporter.datadog import constants, propagator
20-
from opentelemetry.propagators.textmap import DictGetter
2120
from opentelemetry.sdk import trace
2221
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
2322
from opentelemetry.trace import get_current_span, set_span_in_context
2423

2524
FORMAT = propagator.DatadogFormat()
2625

27-
carrier_getter = DictGetter()
28-
2926

3027
class TestDatadogFormat(unittest.TestCase):
3128
@classmethod
@@ -45,7 +42,6 @@ def test_malformed_headers(self):
4542
malformed_parent_id_key = FORMAT.PARENT_ID_KEY + "-x"
4643
context = get_current_span(
4744
FORMAT.extract(
48-
carrier_getter,
4945
{
5046
malformed_trace_id_key: self.serialized_trace_id,
5147
malformed_parent_id_key: self.serialized_parent_id,
@@ -63,7 +59,7 @@ def test_missing_trace_id(self):
6359
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
6460
}
6561

66-
ctx = FORMAT.extract(carrier_getter, carrier)
62+
ctx = FORMAT.extract(carrier)
6763
span_context = get_current_span(ctx).get_span_context()
6864
self.assertEqual(span_context.trace_id, trace_api.INVALID_TRACE_ID)
6965

@@ -73,15 +69,14 @@ def test_missing_parent_id(self):
7369
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
7470
}
7571

76-
ctx = FORMAT.extract(carrier_getter, carrier)
72+
ctx = FORMAT.extract(carrier)
7773
span_context = get_current_span(ctx).get_span_context()
7874
self.assertEqual(span_context.span_id, trace_api.INVALID_SPAN_ID)
7975

8076
def test_context_propagation(self):
8177
"""Test the propagation of Datadog headers."""
8278
parent_span_context = get_current_span(
8379
FORMAT.extract(
84-
carrier_getter,
8580
{
8681
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
8782
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
@@ -118,7 +113,7 @@ def test_context_propagation(self):
118113

119114
child_carrier = {}
120115
child_context = set_span_in_context(child)
121-
FORMAT.inject(dict.__setitem__, child_carrier, context=child_context)
116+
FORMAT.inject(child_carrier, context=child_context)
122117

123118
self.assertEqual(
124119
child_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id
@@ -138,7 +133,6 @@ def test_sampling_priority_auto_reject(self):
138133
"""Test sampling priority rejected."""
139134
parent_span_context = get_current_span(
140135
FORMAT.extract(
141-
carrier_getter,
142136
{
143137
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
144138
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
@@ -165,7 +159,7 @@ def test_sampling_priority_auto_reject(self):
165159

166160
child_carrier = {}
167161
child_context = set_span_in_context(child)
168-
FORMAT.inject(dict.__setitem__, child_carrier, context=child_context)
162+
FORMAT.inject(child_carrier, context=child_context)
169163

170164
self.assertEqual(
171165
child_carrier[FORMAT.SAMPLING_PRIORITY_KEY],
@@ -178,8 +172,6 @@ def test_fields(self, mock_get_current_span):
178172

179173
tracer = trace.TracerProvider().get_tracer("sdk_tracer_provider")
180174

181-
mock_set_in_carrier = Mock()
182-
183175
mock_get_current_span.configure_mock(
184176
**{
185177
"return_value": Mock(
@@ -193,13 +185,10 @@ def test_fields(self, mock_get_current_span):
193185
}
194186
)
195187

188+
carrier = {}
189+
196190
with tracer.start_as_current_span("parent"):
197191
with tracer.start_as_current_span("child"):
198-
FORMAT.inject(mock_set_in_carrier, {})
199-
200-
inject_fields = set()
201-
202-
for call in mock_set_in_carrier.mock_calls:
203-
inject_fields.add(call[1][1])
192+
FORMAT.inject(carrier)
204193

205-
self.assertEqual(FORMAT.fields, inject_fields)
194+
self.assertEqual(FORMAT.fields, carrier.keys())

instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ async def on_request_start(
181181
trace.set_span_in_context(trace_config_ctx.span)
182182
)
183183

184-
inject(type(params.headers).__setitem__, params.headers)
184+
inject(params.headers)
185185

186186
async def on_request_end(
187187
unused_session: aiohttp.ClientSession,

instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py

+23-33
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@
1313
# limitations under the License.
1414

1515
"""
16-
The opentelemetry-instrumentation-asgi package provides an ASGI middleware that can be used
17-
on any ASGI framework (such as Django-channels / Quart) to track requests
18-
timing through OpenTelemetry.
16+
The opentelemetry-instrumentation-asgi package provides an ASGI middleware that
17+
can be used on any ASGI framework (such as Django-channels / Quart) to track
18+
requests timing through OpenTelemetry.
1919
"""
2020

21-
import typing
2221
import urllib
2322
from functools import wraps
2423
from typing import Tuple
@@ -29,46 +28,37 @@
2928
from opentelemetry.instrumentation.asgi.version import __version__ # noqa
3029
from opentelemetry.instrumentation.utils import http_status_to_status_code
3130
from opentelemetry.propagate import extract
32-
from opentelemetry.propagators.textmap import DictGetter
3331
from opentelemetry.trace.status import Status, StatusCode
32+
from opentelemetry.util.http import BaseCustomGetDictionary
3433

3534

36-
class CarrierGetter(DictGetter):
37-
def get(
38-
self, carrier: dict, key: str
39-
) -> typing.Optional[typing.List[str]]:
40-
"""Getter implementation to retrieve a HTTP header value from the ASGI
41-
scope.
35+
class _ASGICustomGetDictionary(BaseCustomGetDictionary):
36+
def get(self, name, default=None):
4237

43-
Args:
44-
carrier: ASGI scope object
45-
key: header name in scope
46-
Returns:
47-
A list with a single string with the header value if it exists,
48-
else None.
49-
"""
50-
headers = carrier.get("headers")
51-
if not headers:
52-
return None
38+
if "headers" not in self.keys():
39+
return default
40+
41+
# ASGI header keys are in lower case
42+
name = name.lower()
5343

54-
# asgi header keys are in lower case
55-
key = key.lower()
5644
decoded = [
57-
_value.decode("utf8")
58-
for (_key, _value) in headers
59-
if _key.decode("utf8") == key
45+
value.decode("utf8")
46+
for key, value in self["headers"]
47+
if key.decode("utf8") == name
6048
]
61-
if not decoded:
62-
return None
63-
return decoded
6449

50+
if not decoded:
51+
return default
6552

66-
carrier_getter = CarrierGetter()
53+
return decoded
6754

6855

6956
def collect_request_attributes(scope):
7057
"""Collects HTTP request attributes from the ASGI scope and returns a
7158
dictionary to be used as span creation attributes."""
59+
60+
asgi_scope = _ASGICustomGetDictionary(scope)
61+
7262
server_host, port, http_url = get_host_port_url_tuple(scope)
7363
query_string = scope.get("query_string")
7464
if query_string and http_url:
@@ -88,10 +78,10 @@ def collect_request_attributes(scope):
8878
if http_method:
8979
result["http.method"] = http_method
9080

91-
http_host_value_list = carrier_getter.get(scope, "host")
81+
http_host_value_list = asgi_scope.get("host")
9282
if http_host_value_list:
9383
result["http.server_name"] = ",".join(http_host_value_list)
94-
http_user_agent = carrier_getter.get(scope, "user-agent")
84+
http_user_agent = asgi_scope.get("user-agent")
9585
if http_user_agent:
9686
result["http.user_agent"] = http_user_agent[0]
9787

@@ -186,7 +176,7 @@ async def __call__(self, scope, receive, send):
186176
if self.excluded_urls and self.excluded_urls.url_disabled(url):
187177
return await self.app(scope, receive, send)
188178

189-
token = context.attach(extract(carrier_getter, scope))
179+
token = context.attach(extract(scope))
190180
span_name, additional_attributes = self.span_details_callback(scope)
191181

192182
try:

0 commit comments

Comments
 (0)