Skip to content

Commit 39b2f56

Browse files
authored
fix(tracing): handle when origin is Py2 unicode (backport #4030) (#4044)
This is an automatic backport of pull request #4030 done by [Mergify](https://mergify.com). --- <details> <summary>Mergify commands and options</summary> <br /> More conditions and actions can be found in the [documentation](https://docs.mergify.com/). You can also trigger Mergify actions by commenting on this pull request: - `@Mergifyio refresh` will re-evaluate the rules - `@Mergifyio rebase` will rebase this PR on its base branch - `@Mergifyio update` will merge the base branch into this PR - `@Mergifyio backport <destination>` will backport this PR on `<destination>` branch Additionally, on Mergify [dashboard](https://dashboard.mergify.com/) you can: - look at your merge queues - generate the Mergify configuration with the config editor. Finally, you can contact us on https://mergify.com </details>
1 parent 9d04c4f commit 39b2f56

File tree

5 files changed

+58
-3
lines changed

5 files changed

+58
-3
lines changed

ddtrace/propagation/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def _extract_header_value(possible_header_names, headers, default=None):
6666
# type: (FrozenSet[str], Dict[str, str], Optional[str]) -> Optional[str]
6767
for header in possible_header_names:
6868
if header in headers:
69-
return headers[header]
69+
return ensure_str(headers[header], errors="backslashreplace")
7070

7171
return default
7272

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
tracing: fix handling of unicode ``_dd.origin`` tag for Python 2

tests/contrib/django/test_django.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,7 @@ def test_django_request_distributed(client, test_spans):
12261226
headers = {
12271227
get_wsgi_header(HTTP_HEADER_TRACE_ID): "12345",
12281228
get_wsgi_header(HTTP_HEADER_PARENT_ID): "78910",
1229-
get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY): USER_KEEP,
1229+
get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY): str(USER_KEEP),
12301230
}
12311231
resp = client.get("/", **headers)
12321232
assert resp.status_code == 200
@@ -1258,7 +1258,7 @@ def test_django_request_distributed_disabled(client, test_spans):
12581258
headers = {
12591259
get_wsgi_header(HTTP_HEADER_TRACE_ID): "12345",
12601260
get_wsgi_header(HTTP_HEADER_PARENT_ID): "78910",
1261-
get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY): USER_KEEP,
1261+
get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY): str(USER_KEEP),
12621262
}
12631263
with override_config("django", dict(distributed_tracing_enabled=False)):
12641264
resp = client.get("/", **headers)

tests/tracer/test_encoders.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,12 @@ def test_encoder_propagates_dd_origin(Encoder, item):
413413
with tracer.trace("child"):
414414
pass
415415
trace = tracer._writer.pop()
416+
assert trace, "DummyWriter failed to encode the trace"
417+
416418
encoder.put(trace)
417419
decoded_trace = decode(encoder.encode())
420+
assert len(decoded_trace) == 1
421+
assert decoded_trace[0]
418422

419423
# Ensure encoded trace contains dd_origin tag in all spans
420424
assert all((_[item][_ORIGIN_KEY] == b"ciapp-test" for _ in decoded_trace[0]))

tests/tracer/test_propagation.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,53 @@ def test_extract(tracer):
174174
}
175175

176176

177+
def test_extract_unicode(tracer):
178+
"""
179+
When input data is unicode
180+
we decode everything to str for Python2
181+
182+
183+
Cython encoder expects `context.dd_origin` to be `str`
184+
which for Python2 means only `str`, and `unicode` is
185+
not accepted. If `context.dd_origin` is `unicode`
186+
then trace encoding will fail and the trace will be
187+
lost.
188+
"""
189+
headers = {
190+
u"x-datadog-trace-id": u"1234",
191+
u"x-datadog-parent-id": u"5678",
192+
u"x-datadog-sampling-priority": u"1",
193+
u"x-datadog-origin": u"synthetics",
194+
u"x-datadog-tags": u"_dd.p.test=value,any=tag",
195+
}
196+
197+
context = HTTPPropagator.extract(headers)
198+
199+
tracer.context_provider.activate(context)
200+
201+
with tracer.trace("local_root_span") as span:
202+
assert span.trace_id == 1234
203+
assert span.parent_id == 5678
204+
assert span.context.sampling_priority == 1
205+
206+
assert span.context.dd_origin == "synthetics"
207+
assert type(span.context.dd_origin) is str
208+
209+
assert span.context._meta == {
210+
"_dd.origin": "synthetics",
211+
"_dd.p.test": "value",
212+
}
213+
with tracer.trace("child_span") as child_span:
214+
assert child_span.trace_id == 1234
215+
assert child_span.parent_id != 5678
216+
assert child_span.context.sampling_priority == 1
217+
assert child_span.context.dd_origin == "synthetics"
218+
assert child_span.context._meta == {
219+
"_dd.origin": "synthetics",
220+
"_dd.p.test": "value",
221+
}
222+
223+
177224
@pytest.mark.parametrize(
178225
"x_datadog_tags, expected_trace_tags",
179226
[

0 commit comments

Comments
 (0)