Skip to content

Commit 8f1865d

Browse files
author
Emanuele Palazzetti
committed
[requests] migrate to the new Config system; remove __init__ wrap
1 parent a36a460 commit 8f1865d

File tree

6 files changed

+111
-28
lines changed

6 files changed

+111
-28
lines changed

ddtrace/contrib/requests/connection.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
1-
import os
21
import logging
32
import ddtrace
43

4+
from ddtrace import config
5+
56
from .constants import DEFAULT_SERVICE
67

78
from ...ext import http
8-
from ...util import asbool
99
from ...propagation.http import HTTPPropagator
1010

1111

1212
log = logging.getLogger(__name__)
1313

1414

15-
def _wrap_session_init(func, instance, args, kwargs):
16-
"""Configure tracing settings when the `Session` is initialized"""
17-
func(*args, **kwargs)
18-
19-
# set tracer settings
20-
distributed_tracing = asbool(os.environ.get('DATADOG_REQUESTS_DISTRIBUTED_TRACING')) or False
21-
service_name = os.environ.get('DATADOG_REQUESTS_SERVICE_NAME') or DEFAULT_SERVICE
22-
setattr(instance, 'distributed_tracing', distributed_tracing)
23-
setattr(instance, 'service_name', service_name)
24-
25-
2615
def _extract_service_name(session, span):
2716
"""Extracts the right service name based on the following logic:
2817
- `requests` is the default service name
@@ -35,7 +24,7 @@ def _extract_service_name(session, span):
3524
The priority can be represented as:
3625
Updated service name > parent service name > default to `requests`.
3726
"""
38-
service_name = getattr(session, 'service_name', DEFAULT_SERVICE)
27+
service_name = config.get_from(session)['service_name']
3928
if (service_name == DEFAULT_SERVICE and
4029
span._parent is not None and
4130
span._parent.service is not None):
@@ -45,11 +34,12 @@ def _extract_service_name(session, span):
4534

4635
def _wrap_request(func, instance, args, kwargs):
4736
"""Trace the `Session.request` instance method"""
37+
# TODO[manu]: we already offer a way to provide the Global Tracer
38+
# and is ddtrace.tracer; it's used only inside our tests and can
39+
# be easily changed by providing a TracingTestCase that sets common
40+
# tracing functionalities.
4841
tracer = getattr(instance, 'datadog_tracer', ddtrace.tracer)
4942

50-
# [TODO:christian] replace this with a unified way of handling options (eg, Pin)
51-
distributed_tracing = getattr(instance, 'distributed_tracing', None)
52-
5343
# skip if tracing is not enabled
5444
if not tracer.enabled:
5545
return func(*args, **kwargs)
@@ -62,7 +52,8 @@ def _wrap_request(func, instance, args, kwargs):
6252
# update the span service name before doing any action
6353
span.service = _extract_service_name(instance, span)
6454

65-
if distributed_tracing:
55+
# propagate distributed tracing headers
56+
if config.get_from(instance)['distributed_tracing']:
6657
propagator = HTTPPropagator()
6758
propagator.inject(span.context, headers)
6859
kwargs['headers'] = headers

ddtrace/contrib/requests/legacy.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from ddtrace import config
2+
3+
4+
def _distributed_tracing(self):
5+
"""Backward compatibility"""
6+
return config.get_from(self)['distributed_tracing']
7+
8+
9+
def _distributed_tracing_setter(self, value):
10+
"""Backward compatibility"""
11+
config.get_from(self)['distributed_tracing'] = value

ddtrace/contrib/requests/patch.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@
22

33
from wrapt import wrap_function_wrapper as _w
44

5-
from ...util import unwrap as _u
6-
from .connection import _wrap_session_init, _wrap_request
5+
from ddtrace import config
6+
from ddtrace.pin import Pin
7+
8+
from ...util import asbool, get_env, unwrap as _u
9+
from .legacy import _distributed_tracing, _distributed_tracing_setter
10+
from .constants import DEFAULT_SERVICE
11+
from .connection import _wrap_request
12+
13+
14+
# requests default settings
15+
config._add('requests',{
16+
'service_name': get_env('requests', 'service_name', DEFAULT_SERVICE),
17+
'distributed_tracing': asbool(get_env('requests', 'distributed_tracing', False)),
18+
})
719

820

921
def patch():
@@ -12,8 +24,18 @@ def patch():
1224
return
1325
setattr(requests, '__datadog_patch', True)
1426

15-
_w('requests', 'Session.__init__', _wrap_session_init)
1627
_w('requests', 'Session.request', _wrap_request)
28+
Pin(
29+
service=config.requests['service_name'],
30+
_config=config.requests,
31+
).onto(requests.Session)
32+
33+
# [Backward compatibility]: `session.distributed_tracing` should point and
34+
# update the `Pin` configuration instead. This block adds a property so that
35+
# old implementations work as expected
36+
fn = property(_distributed_tracing)
37+
fn = fn.setter(_distributed_tracing_setter)
38+
requests.Session.distributed_tracing = fn
1739

1840

1941
def unpatch():
@@ -22,5 +44,4 @@ def unpatch():
2244
return
2345
setattr(requests, '__datadog_patch', False)
2446

25-
_u(requests.Session, '__init__')
2647
_u(requests.Session, 'request')

ddtrace/contrib/requests/session.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from wrapt import wrap_function_wrapper as _w
44

5-
from .connection import _wrap_session_init, _wrap_request
5+
from .connection import _wrap_request
66

77

88
class TracedSession(requests.Session):
@@ -14,5 +14,4 @@ class TracedSession(requests.Session):
1414

1515

1616
# always patch our `TracedSession` when imported
17-
_w(TracedSession, 'request', _wrap_session_init)
1817
_w(TracedSession, 'request', _wrap_request)

tests/contrib/requests/test_requests.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import unittest
22

33
from requests import Session
4-
from nose.tools import eq_, assert_raises
4+
from nose.tools import eq_
55

6+
from ddtrace import config
67
from ddtrace.ext import http, errors
78
from ddtrace.contrib.requests import patch, unpatch
89

@@ -153,7 +154,8 @@ def test_default_service_name(self):
153154

154155
def test_user_set_service_name(self):
155156
# ensure a service name set by the user has precedence
156-
self.session.service_name = 'clients'
157+
cfg = config.get_from(self.session)
158+
cfg['service_name'] = 'clients'
157159
out = self.session.get(URL_200)
158160
eq_(out.status_code, 200)
159161

@@ -194,8 +196,9 @@ def test_parent_without_service_name(self):
194196
def test_user_service_name_precedence(self):
195197
# ensure the user service name takes precedence over
196198
# the parent Span
199+
cfg = config.get_from(self.session)
200+
cfg['service_name'] = 'clients'
197201
with self.tracer.trace('parent.span', service='web'):
198-
self.session.service_name = 'clients'
199202
out = self.session.get(URL_200)
200203
eq_(out.status_code, 200)
201204

tests/contrib/requests/test_requests_distributed.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from requests_mock import Adapter
22
from nose.tools import eq_, assert_in, assert_not_in
33

4+
from ddtrace import config
5+
46
from .test_requests import BaseRequestTestCase
57

68

@@ -24,10 +26,26 @@ def headers_not_here(self, tracer, request):
2426
assert_not_in('x-datadog-parent-id', headers)
2527
return True
2628

29+
def test_propagation_default(self):
30+
# ensure by default, distributed tracing is disabled
31+
adapter = Adapter()
32+
self.session.mount('mock', adapter)
33+
34+
with self.tracer.trace('root'):
35+
def matcher(request):
36+
return self.headers_not_here(self.tracer, request)
37+
adapter.register_uri('GET', 'mock://datadog/foo', additional_matcher=matcher, text='bar')
38+
resp = self.session.get('mock://datadog/foo')
39+
eq_(200, resp.status_code)
40+
eq_('bar', resp.text)
41+
2742
def test_propagation_true(self):
43+
# [Backward compatibility]: ensure users can switch the distributed
44+
# tracing flag using the `Session` attribute
45+
cfg = config.get_from(self.session)
46+
cfg['distributed_tracing'] = True
2847
adapter = Adapter()
2948
self.session.mount('mock', adapter)
30-
self.session.distributed_tracing = True
3149

3250
with self.tracer.trace('root') as root:
3351
def matcher(request):
@@ -45,6 +63,46 @@ def matcher(request):
4563
eq_(root.span_id, req.parent_id)
4664

4765
def test_propagation_false(self):
66+
# [Backward compatibility]: ensure users can switch the distributed
67+
# tracing flag using the `Session` attribute
68+
cfg = config.get_from(self.session)
69+
cfg['distributed_tracing'] = False
70+
adapter = Adapter()
71+
self.session.mount('mock', adapter)
72+
73+
with self.tracer.trace('root'):
74+
def matcher(request):
75+
return self.headers_not_here(self.tracer, request)
76+
adapter.register_uri('GET', 'mock://datadog/foo', additional_matcher=matcher, text='bar')
77+
resp = self.session.get('mock://datadog/foo')
78+
eq_(200, resp.status_code)
79+
eq_('bar', resp.text)
80+
81+
def test_propagation_true_legacy(self):
82+
# [Backward compatibility]: ensure users can switch the distributed
83+
# tracing flag using the `Session` attribute
84+
adapter = Adapter()
85+
self.session.mount('mock', adapter)
86+
self.session.distributed_tracing = True
87+
88+
with self.tracer.trace('root') as root:
89+
def matcher(request):
90+
return self.headers_here(self.tracer, request, root)
91+
adapter.register_uri('GET', 'mock://datadog/foo', additional_matcher=matcher, text='bar')
92+
resp = self.session.get('mock://datadog/foo')
93+
eq_(200, resp.status_code)
94+
eq_('bar', resp.text)
95+
96+
spans = self.tracer.writer.spans
97+
root, req = spans
98+
eq_('root', root.name)
99+
eq_('requests.request', req.name)
100+
eq_(root.trace_id, req.trace_id)
101+
eq_(root.span_id, req.parent_id)
102+
103+
def test_propagation_false_legacy(self):
104+
# [Backward compatibility]: ensure users can switch the distributed
105+
# tracing flag using the `Session` attribute
48106
adapter = Adapter()
49107
self.session.mount('mock', adapter)
50108
self.session.distributed_tracing = False

0 commit comments

Comments
 (0)